blob: a7984e5f7158900b96fb3960c48a6219274c71c8 [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>
Urvang Joshibc82d382019-11-01 17:59:20 -070013#include <float.h>
Yaowu Xuc27fc142016-08-22 16:08:15 -070014#include <math.h>
15#include <stdio.h>
16
Tom Finegan60e653d2018-05-22 11:34:58 -070017#include "config/aom_config.h"
Tom Finegan44702c82018-05-22 13:00:39 -070018#include "config/aom_dsp_rtcd.h"
19#include "config/aom_scale_rtcd.h"
Yaowu Xufa3721d2018-07-30 14:38:49 -070020#include "config/av1_rtcd.h"
21
22#include "aom_dsp/aom_dsp_common.h"
23#include "aom_dsp/aom_filter.h"
24#if CONFIG_DENOISE
25#include "aom_dsp/grain_table.h"
26#include "aom_dsp/noise_util.h"
27#include "aom_dsp/noise_model.h"
28#endif
29#include "aom_dsp/psnr.h"
30#if CONFIG_INTERNAL_STATS
31#include "aom_dsp/ssim.h"
32#endif
33#include "aom_ports/aom_timer.h"
34#include "aom_ports/mem.h"
35#include "aom_ports/system_state.h"
36#include "aom_scale/aom_scale.h"
David Turner1539bb02019-01-24 15:28:13 +000037#if CONFIG_BITSTREAM_DEBUG
Yaowu Xufa3721d2018-07-30 14:38:49 -070038#include "aom_util/debug_util.h"
David Turner1539bb02019-01-24 15:28:13 +000039#endif // CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070040
41#include "av1/common/alloccommon.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070042#include "av1/common/filter.h"
43#include "av1/common/idct.h"
44#include "av1/common/reconinter.h"
45#include "av1/common/reconintra.h"
Fergus Simpsond0565002017-03-27 16:51:52 -070046#include "av1/common/resize.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070047#include "av1/common/tile_common.h"
48
49#include "av1/encoder/aq_complexity.h"
50#include "av1/encoder/aq_cyclicrefresh.h"
51#include "av1/encoder/aq_variance.h"
52#include "av1/encoder/bitstream.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070053#include "av1/encoder/context_tree.h"
54#include "av1/encoder/encodeframe.h"
55#include "av1/encoder/encodemv.h"
David Turner056f7cd2019-01-07 17:48:13 +000056#include "av1/encoder/encode_strategy.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070057#include "av1/encoder/encoder.h"
Satish Kumar Sumand3caa0d2020-06-16 14:02:50 +053058#include "av1/encoder/encoder_alloc.h"
Satish Kumar Suman897b7942020-06-11 11:44:29 +053059#include "av1/encoder/encoder_utils.h"
Angie Chiangf0fbf9d2017-03-15 15:01:22 -070060#include "av1/encoder/encodetxb.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070061#include "av1/encoder/ethread.h"
62#include "av1/encoder/firstpass.h"
Yaowu Xufa3721d2018-07-30 14:38:49 -070063#include "av1/encoder/grain_test_vectors.h"
RogerZhoucc5d35d2017-08-07 22:20:15 -070064#include "av1/encoder/hash_motion.h"
chiyotsai73ddf442020-06-01 15:42:23 -070065#include "av1/encoder/intra_mode_search.h"
chiyotsaic666b1f2019-12-20 10:44:58 -080066#include "av1/encoder/mv_prec.h"
David Turner0fa8c492019-02-06 16:38:13 +000067#include "av1/encoder/pass2_strategy.h"
Debargha Mukherjee2d565f42020-06-17 18:07:12 -070068#include "av1/encoder/pickcdef.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070069#include "av1/encoder/picklpf.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070070#include "av1/encoder/pickrst.h"
Debargha Mukherjee7166f222017-09-05 21:32:42 -070071#include "av1/encoder/random.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070072#include "av1/encoder/ratectrl.h"
Satish Kumar Suman47c06892020-06-10 12:45:25 +053073#include "av1/encoder/rc_utils.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070074#include "av1/encoder/rd.h"
Debargha Mukherjeedf713102018-10-02 12:33:32 -070075#include "av1/encoder/rdopt.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070076#include "av1/encoder/segmentation.h"
77#include "av1/encoder/speed_features.h"
Satish Kumar Suman7a5f5f42020-06-09 14:20:47 +053078#include "av1/encoder/superres_scale.h"
Debargha Mukherjee347c64d2019-05-08 13:53:46 -070079#include "av1/encoder/tpl_model.h"
Yue Chen7cae98f2018-08-24 10:43:16 -070080#include "av1/encoder/reconinter_enc.h"
kyslov7b9d0d62018-12-21 11:12:26 -080081#include "av1/encoder/var_based_part.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070082
sdenge63f9fa2019-12-13 09:29:55 -080083#if CONFIG_TUNE_VMAF
84#include "av1/encoder/tune_vmaf.h"
85#endif
86
Imdad Sardharwallae68aa8a2018-03-07 18:52:54 +000087#define DEFAULT_EXPLICIT_ORDER_HINT_BITS 7
Imdad Sardharwallae68aa8a2018-03-07 18:52:54 +000088
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -080089#if CONFIG_ENTROPY_STATS
90FRAME_COUNTS aggregate_fc;
91#endif // CONFIG_ENTROPY_STATS
92
Yaowu Xuc27fc142016-08-22 16:08:15 -070093// #define OUTPUT_YUV_REC
Yaowu Xuc27fc142016-08-22 16:08:15 -070094#ifdef OUTPUT_YUV_REC
95FILE *yuv_rec_file;
96#define FILE_NAME_LEN 100
97#endif
98
Yaowu Xuf883b422016-08-30 14:01:10 -070099static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700100 switch (mode) {
101 case NORMAL:
102 *hr = 1;
103 *hs = 1;
104 break;
105 case FOURFIVE:
106 *hr = 4;
107 *hs = 5;
108 break;
109 case THREEFIVE:
110 *hr = 3;
111 *hs = 5;
112 break;
Marco Paniconi4e869372020-06-23 10:22:50 -0700113 case THREEFOUR:
114 *hr = 3;
115 *hs = 4;
116 break;
117 case ONEFOUR:
118 *hr = 1;
119 *hs = 4;
120 break;
121 case ONEEIGHT:
122 *hr = 1;
123 *hs = 8;
124 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700125 case ONETWO:
126 *hr = 1;
127 *hs = 2;
128 break;
129 default:
130 *hr = 1;
131 *hs = 1;
132 assert(0);
133 break;
134 }
135}
136
Yaowu Xuf883b422016-08-30 14:01:10 -0700137static void apply_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700138 struct segmentation *const seg = &cpi->common.seg;
Vishesh8c90fff2020-04-13 11:32:56 +0530139 unsigned char *const seg_map = cpi->enc_seg.map;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700140 const unsigned char *const active_map = cpi->active_map.map;
141 int i;
142
143 assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);
144
145 if (frame_is_intra_only(&cpi->common)) {
146 cpi->active_map.enabled = 0;
147 cpi->active_map.update = 1;
148 }
149
150 if (cpi->active_map.update) {
151 if (cpi->active_map.enabled) {
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700152 for (i = 0;
153 i < cpi->common.mi_params.mi_rows * cpi->common.mi_params.mi_cols;
154 ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700155 if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
Yaowu Xuf883b422016-08-30 14:01:10 -0700156 av1_enable_segmentation(seg);
157 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
Cheng Chend8184da2017-09-26 18:15:22 -0700158 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H);
159 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V);
160 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U);
161 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V);
162
163 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H,
164 -MAX_LOOP_FILTER);
165 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V,
166 -MAX_LOOP_FILTER);
167 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U,
168 -MAX_LOOP_FILTER);
169 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V,
170 -MAX_LOOP_FILTER);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700171 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700172 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
Cheng Chend8184da2017-09-26 18:15:22 -0700173 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H);
174 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V);
175 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U);
176 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700177 if (seg->enabled) {
178 seg->update_data = 1;
179 seg->update_map = 1;
180 }
181 }
182 cpi->active_map.update = 0;
183 }
184}
185
Yaowu Xuf883b422016-08-30 14:01:10 -0700186int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
187 int cols) {
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700188 const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
189 if (rows == mi_params->mb_rows && cols == mi_params->mb_cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190 unsigned char *const active_map_8x8 = cpi->active_map.map;
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700191 const int mi_rows = mi_params->mi_rows;
192 const int mi_cols = mi_params->mi_cols;
Jingning Han9d533022017-04-07 10:14:42 -0700193 const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
194 const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700195 cpi->active_map.update = 1;
196 if (new_map_16x16) {
197 int r, c;
198 for (r = 0; r < mi_rows; ++r) {
199 for (c = 0; c < mi_cols; ++c) {
200 active_map_8x8[r * mi_cols + c] =
Jingning Han9d533022017-04-07 10:14:42 -0700201 new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)]
Yaowu Xuc27fc142016-08-22 16:08:15 -0700202 ? AM_SEGMENT_ID_ACTIVE
203 : AM_SEGMENT_ID_INACTIVE;
204 }
205 }
206 cpi->active_map.enabled = 1;
207 } else {
208 cpi->active_map.enabled = 0;
209 }
210 return 0;
211 } else {
212 return -1;
213 }
214}
215
Yaowu Xuf883b422016-08-30 14:01:10 -0700216int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
217 int cols) {
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700218 const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
219 if (rows == mi_params->mb_rows && cols == mi_params->mb_cols &&
Yaowu Xuc27fc142016-08-22 16:08:15 -0700220 new_map_16x16) {
Vishesh8c90fff2020-04-13 11:32:56 +0530221 unsigned char *const seg_map_8x8 = cpi->enc_seg.map;
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700222 const int mi_rows = mi_params->mi_rows;
223 const int mi_cols = mi_params->mi_cols;
Jingning Han9d533022017-04-07 10:14:42 -0700224 const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
225 const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
226
Yaowu Xuc27fc142016-08-22 16:08:15 -0700227 memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
228 if (cpi->active_map.enabled) {
229 int r, c;
230 for (r = 0; r < mi_rows; ++r) {
231 for (c = 0; c < mi_cols; ++c) {
232 // Cyclic refresh segments are considered active despite not having
233 // AM_SEGMENT_ID_ACTIVE
Jingning Han9d533022017-04-07 10:14:42 -0700234 new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)] |=
Yaowu Xuc27fc142016-08-22 16:08:15 -0700235 seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
236 }
237 }
238 }
239 return 0;
240 } else {
241 return -1;
242 }
243}
244
Yaowu Xuf883b422016-08-30 14:01:10 -0700245static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
Urvang Joshie4530f82018-01-09 11:43:37 -0800246 const AV1_COMMON *const cm = &cpi->common;
Vishesh0d279aa2020-06-03 15:56:56 +0530247 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
James Zernbf3ca362019-10-21 11:33:44 -0700248
Vishesh0d279aa2020-06-03 15:56:56 +0530249 if (oxcf->superblock_size == AOM_SUPERBLOCK_SIZE_64X64) return BLOCK_64X64;
250 if (oxcf->superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
Ryan Leic8b6dd62019-10-23 20:01:26 -0700251 return BLOCK_128X128;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700252
Vishesh0d279aa2020-06-03 15:56:56 +0530253 assert(oxcf->superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700254
Marco Paniconi72056922020-06-24 12:31:25 -0700255 if (cpi->svc.number_spatial_layers > 1 ||
256 oxcf->resize_cfg.resize_mode != RESIZE_NONE) {
257 // Use the configured size (top resolution) for spatial layers or
258 // on resize.
Vishesh2b8e4792020-06-12 12:11:19 +0530259 return AOMMIN(oxcf->frm_dim_cfg.width, oxcf->frm_dim_cfg.height) > 480
260 ? BLOCK_128X128
261 : BLOCK_64X64;
Marco Paniconi8c449df2020-04-02 23:41:46 -0700262 }
263
Ryan Leic8b6dd62019-10-23 20:01:26 -0700264 // TODO(any): Possibly could improve this with a heuristic.
Urvang Joshiaab74432018-06-01 12:06:22 -0700265 // When superres / resize is on, 'cm->width / height' can change between
Hui Su3e3b9342019-04-12 18:27:28 +0000266 // calls, so we don't apply this heuristic there.
267 // Things break if superblock size changes between the first pass and second
268 // pass encoding, which is why this heuristic is not configured as a
269 // speed-feature.
Vishesh0d279aa2020-06-03 15:56:56 +0530270 if (oxcf->superres_cfg.superres_mode == AOM_SUPERRES_NONE &&
Vishesh217bf912020-06-05 16:24:09 +0530271 oxcf->resize_cfg.resize_mode == RESIZE_NONE && oxcf->speed >= 1) {
Hui Su3e3b9342019-04-12 18:27:28 +0000272 return AOMMIN(cm->width, cm->height) > 480 ? BLOCK_128X128 : BLOCK_64X64;
Urvang Joshie4530f82018-01-09 11:43:37 -0800273 }
274
Yaowu Xuc27fc142016-08-22 16:08:15 -0700275 return BLOCK_128X128;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700276}
277
Yaowu Xuf883b422016-08-30 14:01:10 -0700278static void setup_frame(AV1_COMP *cpi) {
279 AV1_COMMON *const cm = &cpi->common;
Johannb0ef6ff2018-02-08 14:32:21 -0800280 // Set up entropy context depending on frame type. The decoder mandates
281 // the use of the default context, index 0, for keyframes and inter
282 // frames where the error_resilient_mode or intra_only flag is set. For
283 // other inter-frames the encoder currently uses only two contexts;
284 // context 1 for ALTREF frames and context 0 for the others.
Soo-Chul Han85e8c792018-01-21 01:58:15 -0500285
Urvang Joshib6409e92020-03-23 11:23:27 -0700286 if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
Vishesha195ca32020-04-07 18:46:20 +0530287 cpi->ext_flags.use_primary_ref_none) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700288 av1_setup_past_independence(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700289 }
290
Hui Sueb4b7de2019-04-03 11:00:18 -0700291 if ((cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) ||
292 frame_is_sframe(cm)) {
293 if (!cpi->seq_params_locked) {
294 set_sb_size(&cm->seq_params, select_sb_size(cpi));
295 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700296 } else {
David Turnera21966b2018-12-05 14:48:49 +0000297 const RefCntBuffer *const primary_ref_buf = get_primary_ref_frame_buf(cm);
298 if (primary_ref_buf == NULL) {
David Barkercc615a82018-03-19 14:38:51 +0000299 av1_setup_past_independence(cm);
300 cm->seg.update_map = 1;
301 cm->seg.update_data = 1;
Thomas Daededa4d8b92017-06-05 15:44:14 -0700302 } else {
David Turnera21966b2018-12-05 14:48:49 +0000303 *cm->fc = primary_ref_buf->frame_context;
Thomas Daededa4d8b92017-06-05 15:44:14 -0700304 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700305 }
306
David Turnerbc0993e2019-02-15 14:42:23 +0000307 av1_zero(cm->cur_frame->interp_filter_selected);
David Turnera21966b2018-12-05 14:48:49 +0000308 cm->prev_frame = get_primary_ref_frame_buf(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700309 cpi->vaq_refresh = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700310}
311
Yaowu Xuf883b422016-08-30 14:01:10 -0700312void av1_initialize_enc(void) {
Wan-Teh Chang3cac4542018-06-29 10:21:39 -0700313 av1_rtcd();
314 aom_dsp_rtcd();
315 aom_scale_rtcd();
316 av1_init_intra_predictors();
317 av1_init_me_luts();
318 av1_rc_init_minq_luts();
319 av1_init_wedge_masks();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700320}
321
Yaowu Xuc0ea2582019-01-15 10:17:16 -0800322static void reset_film_grain_chroma_params(aom_film_grain_t *pars) {
323 pars->num_cr_points = 0;
324 pars->cr_mult = 0;
325 pars->cr_luma_mult = 0;
326 memset(pars->scaling_points_cr, 0, sizeof(pars->scaling_points_cr));
327 memset(pars->ar_coeffs_cr, 0, sizeof(pars->ar_coeffs_cr));
328 pars->num_cb_points = 0;
329 pars->cb_mult = 0;
330 pars->cb_luma_mult = 0;
Yaowu Xufda7dcb2019-01-16 13:04:33 -0800331 pars->chroma_scaling_from_luma = 0;
Yaowu Xuc0ea2582019-01-15 10:17:16 -0800332 memset(pars->scaling_points_cb, 0, sizeof(pars->scaling_points_cb));
333 memset(pars->ar_coeffs_cb, 0, sizeof(pars->ar_coeffs_cb));
334}
335
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800336static void update_film_grain_parameters(struct AV1_COMP *cpi,
337 const AV1EncoderConfig *oxcf) {
338 AV1_COMMON *const cm = &cpi->common;
339 cpi->oxcf = *oxcf;
340
Neil Birkbecka2893ab2018-06-08 14:45:13 -0700341 if (cpi->film_grain_table) {
342 aom_film_grain_table_free(cpi->film_grain_table);
343 aom_free(cpi->film_grain_table);
344 cpi->film_grain_table = NULL;
Neil Birkbeckeb895ef2018-03-14 17:51:03 -0700345 }
Neil Birkbeckeb895ef2018-03-14 17:51:03 -0700346
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800347 if (oxcf->film_grain_test_vector) {
Urvang Joshi8d5a4ba2018-07-19 16:26:34 -0700348 cm->seq_params.film_grain_params_present = 1;
David Turnerd2a592e2018-11-16 14:59:31 +0000349 if (cm->current_frame.frame_type == KEY_FRAME) {
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800350 memcpy(&cm->film_grain_params,
351 film_grain_test_vectors + oxcf->film_grain_test_vector - 1,
352 sizeof(cm->film_grain_params));
Yaowu Xuc0ea2582019-01-15 10:17:16 -0800353 if (oxcf->monochrome)
354 reset_film_grain_chroma_params(&cm->film_grain_params);
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700355 cm->film_grain_params.bit_depth = cm->seq_params.bit_depth;
356 if (cm->seq_params.color_range == AOM_CR_FULL_RANGE) {
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800357 cm->film_grain_params.clip_to_restricted_range = 0;
358 }
359 }
Neil Birkbeckeb895ef2018-03-14 17:51:03 -0700360 } else if (oxcf->film_grain_table_filename) {
Neil Birkbeckbd40ca72019-03-02 13:25:50 -0800361 cm->seq_params.film_grain_params_present = 1;
362
Neil Birkbecka2893ab2018-06-08 14:45:13 -0700363 cpi->film_grain_table = aom_malloc(sizeof(*cpi->film_grain_table));
364 memset(cpi->film_grain_table, 0, sizeof(aom_film_grain_table_t));
Neil Birkbeckeb895ef2018-03-14 17:51:03 -0700365
Neil Birkbecka2893ab2018-06-08 14:45:13 -0700366 aom_film_grain_table_read(cpi->film_grain_table,
Neil Birkbeckeb895ef2018-03-14 17:51:03 -0700367 oxcf->film_grain_table_filename, &cm->error);
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800368 } else {
Neil Birkbeckbd40ca72019-03-02 13:25:50 -0800369#if CONFIG_DENOISE
370 cm->seq_params.film_grain_params_present = (cpi->oxcf.noise_level > 0);
371#else
Urvang Joshi8d5a4ba2018-07-19 16:26:34 -0700372 cm->seq_params.film_grain_params_present = 0;
Neil Birkbeckbd40ca72019-03-02 13:25:50 -0800373#endif
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800374 memset(&cm->film_grain_params, 0, sizeof(cm->film_grain_params));
375 }
376}
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800377
Yaowu Xuf883b422016-08-30 14:01:10 -0700378static void configure_static_seg_features(AV1_COMP *cpi) {
379 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700380 const RATE_CONTROL *const rc = &cpi->rc;
381 struct segmentation *const seg = &cm->seg;
382
383 int high_q = (int)(rc->avg_q > 48.0);
384 int qi_delta;
385
386 // Disable and clear down for KF
David Turnerd2a592e2018-11-16 14:59:31 +0000387 if (cm->current_frame.frame_type == KEY_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700388 // Clear down the global segmentation map
Vishesh8c90fff2020-04-13 11:32:56 +0530389 memset(cpi->enc_seg.map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700390 seg->update_map = 0;
391 seg->update_data = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700392
393 // Disable segmentation
Yaowu Xuf883b422016-08-30 14:01:10 -0700394 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700395
396 // Clear down the segment features.
Yaowu Xuf883b422016-08-30 14:01:10 -0700397 av1_clearall_segfeatures(seg);
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530398 } else if (cpi->refresh_frame.alt_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399 // If this is an alt ref frame
400 // Clear down the global segmentation map
Vishesh8c90fff2020-04-13 11:32:56 +0530401 memset(cpi->enc_seg.map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700402 seg->update_map = 0;
403 seg->update_data = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700404
405 // Disable segmentation and individual segment features by default
Yaowu Xuf883b422016-08-30 14:01:10 -0700406 av1_disable_segmentation(seg);
407 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408
Yaowu Xuc27fc142016-08-22 16:08:15 -0700409 // If segmentation was enabled set those features needed for the
410 // arf itself.
411 if (seg->enabled) {
412 seg->update_map = 1;
413 seg->update_data = 1;
414
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700415 qi_delta = av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875,
416 cm->seq_params.bit_depth);
Yaowu Xuf883b422016-08-30 14:01:10 -0700417 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
Cheng Chend8184da2017-09-26 18:15:22 -0700418 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_H, -2);
419 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_V, -2);
420 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_U, -2);
421 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_V, -2);
422
423 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_H);
424 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_V);
425 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_U);
426 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_V);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427
Yaowu Xuf883b422016-08-30 14:01:10 -0700428 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700429 }
430 } else if (seg->enabled) {
431 // All other frames if segmentation has been enabled
432
433 // First normal frame in a valid gf or alt ref group
434 if (rc->frames_since_golden == 0) {
435 // Set up segment features for normal frames in an arf group
436 if (rc->source_alt_ref_active) {
437 seg->update_map = 0;
438 seg->update_data = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700439
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700440 qi_delta = av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125,
441 cm->seq_params.bit_depth);
Yaowu Xuf883b422016-08-30 14:01:10 -0700442 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
443 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700444
Cheng Chend8184da2017-09-26 18:15:22 -0700445 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_H, -2);
446 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_V, -2);
447 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_U, -2);
448 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_V, -2);
449
450 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_H);
451 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_V);
452 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_U);
453 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_V);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700454
455 // Segment coding disabled for compred testing
Visheshb1f6eb62020-03-31 13:43:35 +0530456 if (high_q) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700457 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
458 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
459 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700460 }
461 } else {
462 // Disable segmentation and clear down features if alt ref
463 // is not active for this group
464
Yaowu Xuf883b422016-08-30 14:01:10 -0700465 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700466
Vishesh8c90fff2020-04-13 11:32:56 +0530467 memset(cpi->enc_seg.map, 0,
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700468 cm->mi_params.mi_rows * cm->mi_params.mi_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700469
470 seg->update_map = 0;
471 seg->update_data = 0;
472
Yaowu Xuf883b422016-08-30 14:01:10 -0700473 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700474 }
475 } else if (rc->is_src_frame_alt_ref) {
476 // Special case where we are coding over the top of a previous
477 // alt ref frame.
478 // Segment coding disabled for compred testing
479
480 // Enable ref frame features for segment 0 as well
Yaowu Xuf883b422016-08-30 14:01:10 -0700481 av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
482 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700483
484 // All mbs should use ALTREF_FRAME
Yaowu Xuf883b422016-08-30 14:01:10 -0700485 av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
486 av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
487 av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
488 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700489
490 // Skip all MBs if high Q (0,0 mv and skip coeffs)
491 if (high_q) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700492 av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
493 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700494 }
495 // Enable data update
496 seg->update_data = 1;
497 } else {
498 // All other frames.
499
500 // No updates.. leave things as they are.
501 seg->update_map = 0;
502 seg->update_data = 0;
503 }
504 }
505}
506
Yaowu Xuf883b422016-08-30 14:01:10 -0700507static void update_reference_segmentation_map(AV1_COMP *cpi) {
508 AV1_COMMON *const cm = &cpi->common;
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700509 const CommonModeInfoParams *const mi_params = &cm->mi_params;
510 MB_MODE_INFO **mi_4x4_ptr = mi_params->mi_grid_base;
David Turnerb757ce02018-11-12 15:01:28 +0000511 uint8_t *cache_ptr = cm->cur_frame->seg_map;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700512
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700513 for (int row = 0; row < mi_params->mi_rows; row++) {
Yushin Choa7f65922018-04-04 16:06:11 -0700514 MB_MODE_INFO **mi_4x4 = mi_4x4_ptr;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700515 uint8_t *cache = cache_ptr;
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700516 for (int col = 0; col < mi_params->mi_cols; col++, mi_4x4++, cache++)
Yushin Choa7f65922018-04-04 16:06:11 -0700517 cache[0] = mi_4x4[0]->segment_id;
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700518 mi_4x4_ptr += mi_params->mi_stride;
519 cache_ptr += mi_params->mi_cols;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700520 }
521}
522
Yaowu Xuf883b422016-08-30 14:01:10 -0700523void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700524 cpi->framerate = framerate < 0.1 ? 30 : framerate;
Debargha Mukherjee7166f222017-09-05 21:32:42 -0700525 av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700526}
527
Hui Suef139e12019-05-20 15:51:22 -0700528double av1_get_compression_ratio(const AV1_COMMON *const cm,
529 size_t encoded_frame_size) {
530 const int upscaled_width = cm->superres_upscaled_width;
531 const int height = cm->height;
532 const int luma_pic_size = upscaled_width * height;
533 const SequenceHeader *const seq_params = &cm->seq_params;
534 const BITSTREAM_PROFILE profile = seq_params->profile;
535 const int pic_size_profile_factor =
536 profile == PROFILE_0 ? 15 : (profile == PROFILE_1 ? 30 : 36);
537 encoded_frame_size =
538 (encoded_frame_size > 129 ? encoded_frame_size - 128 : 1);
539 const size_t uncompressed_frame_size =
540 (luma_pic_size * pic_size_profile_factor) >> 3;
541 return uncompressed_frame_size / (double)encoded_frame_size;
542}
543
Vishesh0481a782020-06-11 14:32:46 +0530544static void set_tile_info(AV1_COMMON *const cm,
545 const TileConfig *const tile_cfg) {
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700546 const CommonModeInfoParams *const mi_params = &cm->mi_params;
Urvang Joshi54ffae72020-03-23 13:37:10 -0700547 const SequenceHeader *const seq_params = &cm->seq_params;
548 CommonTileParams *const tiles = &cm->tiles;
Dominic Symesf58f1112017-09-25 12:47:40 +0200549 int i, start_sb;
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200550
551 av1_get_tile_limits(cm);
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200552
553 // configure tile columns
Vishesh0481a782020-06-11 14:32:46 +0530554 if (tile_cfg->tile_width_count == 0 || tile_cfg->tile_height_count == 0) {
Urvang Joshi54ffae72020-03-23 13:37:10 -0700555 tiles->uniform_spacing = 1;
Vishesh0481a782020-06-11 14:32:46 +0530556 tiles->log2_cols = AOMMAX(tile_cfg->tile_columns, tiles->min_log2_cols);
Urvang Joshi54ffae72020-03-23 13:37:10 -0700557 tiles->log2_cols = AOMMIN(tiles->log2_cols, tiles->max_log2_cols);
Dominic Symesf58f1112017-09-25 12:47:40 +0200558 } else {
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700559 int mi_cols =
560 ALIGN_POWER_OF_TWO(mi_params->mi_cols, seq_params->mib_size_log2);
Urvang Joshi54ffae72020-03-23 13:37:10 -0700561 int sb_cols = mi_cols >> seq_params->mib_size_log2;
Dominic Symes26ad0b22017-10-01 16:35:13 +0200562 int size_sb, j = 0;
Urvang Joshi54ffae72020-03-23 13:37:10 -0700563 tiles->uniform_spacing = 0;
Dominic Symesf58f1112017-09-25 12:47:40 +0200564 for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) {
Urvang Joshi54ffae72020-03-23 13:37:10 -0700565 tiles->col_start_sb[i] = start_sb;
Vishesh0481a782020-06-11 14:32:46 +0530566 size_sb = tile_cfg->tile_widths[j++];
567 if (j >= tile_cfg->tile_width_count) j = 0;
Urvang Joshi54ffae72020-03-23 13:37:10 -0700568 start_sb += AOMMIN(size_sb, tiles->max_width_sb);
Dominic Symesf58f1112017-09-25 12:47:40 +0200569 }
Urvang Joshi54ffae72020-03-23 13:37:10 -0700570 tiles->cols = i;
571 tiles->col_start_sb[i] = sb_cols;
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200572 }
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700573 av1_calculate_tile_cols(seq_params, mi_params->mi_rows, mi_params->mi_cols,
574 tiles);
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200575
576 // configure tile rows
Urvang Joshi54ffae72020-03-23 13:37:10 -0700577 if (tiles->uniform_spacing) {
Vishesh0481a782020-06-11 14:32:46 +0530578 tiles->log2_rows = AOMMAX(tile_cfg->tile_rows, tiles->min_log2_rows);
Urvang Joshi54ffae72020-03-23 13:37:10 -0700579 tiles->log2_rows = AOMMIN(tiles->log2_rows, tiles->max_log2_rows);
Dominic Symesf58f1112017-09-25 12:47:40 +0200580 } else {
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700581 int mi_rows =
582 ALIGN_POWER_OF_TWO(mi_params->mi_rows, seq_params->mib_size_log2);
Urvang Joshi54ffae72020-03-23 13:37:10 -0700583 int sb_rows = mi_rows >> seq_params->mib_size_log2;
Dominic Symes26ad0b22017-10-01 16:35:13 +0200584 int size_sb, j = 0;
Dominic Symesf58f1112017-09-25 12:47:40 +0200585 for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) {
Urvang Joshi54ffae72020-03-23 13:37:10 -0700586 tiles->row_start_sb[i] = start_sb;
Vishesh0481a782020-06-11 14:32:46 +0530587 size_sb = tile_cfg->tile_heights[j++];
588 if (j >= tile_cfg->tile_height_count) j = 0;
Urvang Joshi54ffae72020-03-23 13:37:10 -0700589 start_sb += AOMMIN(size_sb, tiles->max_height_sb);
Dominic Symesf58f1112017-09-25 12:47:40 +0200590 }
Urvang Joshi54ffae72020-03-23 13:37:10 -0700591 tiles->rows = i;
592 tiles->row_start_sb[i] = sb_rows;
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200593 }
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700594 av1_calculate_tile_rows(seq_params, mi_params->mi_rows, tiles);
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200595}
596
Yaowu Xuf883b422016-08-30 14:01:10 -0700597static void update_frame_size(AV1_COMP *cpi) {
598 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
600
chiyotsaia7091f12019-08-09 16:48:27 -0700601 // We need to reallocate the context buffers here in case we need more mis.
602 if (av1_alloc_context_buffers(cm, cm->width, cm->height)) {
603 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
604 "Failed to allocate context buffers");
605 }
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700606 av1_init_mi_buffers(&cm->mi_params);
chiyotsaia7091f12019-08-09 16:48:27 -0700607
Urvang Joshi9543ad72020-04-17 16:59:46 -0700608 av1_init_macroblockd(cm, xd);
chiyotsai426c0662019-08-05 16:15:11 -0700609
Visheshd1317912020-04-07 14:39:44 +0530610 if (!is_stat_generation_stage(cpi))
611 alloc_context_buffers_ext(cm, &cpi->mbmi_ext_info);
Vishesh0481a782020-06-11 14:32:46 +0530612 set_tile_info(cm, &cpi->oxcf.tile_cfg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700613}
614
Debargha Mukherjee57498692018-05-11 13:29:31 -0700615static INLINE int does_level_match(int width, int height, double fps,
616 int lvl_width, int lvl_height,
617 double lvl_fps, int lvl_dim_mult) {
618 const int64_t lvl_luma_pels = lvl_width * lvl_height;
619 const double lvl_display_sample_rate = lvl_luma_pels * lvl_fps;
620 const int64_t luma_pels = width * height;
621 const double display_sample_rate = luma_pels * fps;
622 return luma_pels <= lvl_luma_pels &&
623 display_sample_rate <= lvl_display_sample_rate &&
624 width <= lvl_width * lvl_dim_mult &&
625 height <= lvl_height * lvl_dim_mult;
626}
627
Andrey Norkin26495512018-06-20 17:13:11 -0700628static void set_bitstream_level_tier(SequenceHeader *seq, AV1_COMMON *cm,
Vishesh2b8e4792020-06-12 12:11:19 +0530629 int width, int height,
630 double init_framerate) {
Debargha Mukherjee57498692018-05-11 13:29:31 -0700631 // TODO(any): This is a placeholder function that only addresses dimensions
632 // and max display sample rates.
633 // Need to add checks for max bit rate, max decoded luma sample rate, header
634 // rate, etc. that are not covered by this function.
Hui Su8427ff22019-03-11 10:14:33 -0700635 AV1_LEVEL level = SEQ_LEVEL_MAX;
Vishesh2b8e4792020-06-12 12:11:19 +0530636 if (does_level_match(width, height, init_framerate, 512, 288, 30.0, 4)) {
Hui Su8427ff22019-03-11 10:14:33 -0700637 level = SEQ_LEVEL_2_0;
Vishesh2b8e4792020-06-12 12:11:19 +0530638 } else if (does_level_match(width, height, init_framerate, 704, 396, 30.0,
639 4)) {
Hui Su8427ff22019-03-11 10:14:33 -0700640 level = SEQ_LEVEL_2_1;
Vishesh2b8e4792020-06-12 12:11:19 +0530641 } else if (does_level_match(width, height, init_framerate, 1088, 612, 30.0,
642 4)) {
Hui Su8427ff22019-03-11 10:14:33 -0700643 level = SEQ_LEVEL_3_0;
Vishesh2b8e4792020-06-12 12:11:19 +0530644 } else if (does_level_match(width, height, init_framerate, 1376, 774, 30.0,
645 4)) {
Hui Su8427ff22019-03-11 10:14:33 -0700646 level = SEQ_LEVEL_3_1;
Vishesh2b8e4792020-06-12 12:11:19 +0530647 } else if (does_level_match(width, height, init_framerate, 2048, 1152, 30.0,
648 3)) {
Hui Su8427ff22019-03-11 10:14:33 -0700649 level = SEQ_LEVEL_4_0;
Vishesh2b8e4792020-06-12 12:11:19 +0530650 } else if (does_level_match(width, height, init_framerate, 2048, 1152, 60.0,
651 3)) {
Hui Su8427ff22019-03-11 10:14:33 -0700652 level = SEQ_LEVEL_4_1;
Vishesh2b8e4792020-06-12 12:11:19 +0530653 } else if (does_level_match(width, height, init_framerate, 4096, 2176, 30.0,
654 2)) {
Hui Su8427ff22019-03-11 10:14:33 -0700655 level = SEQ_LEVEL_5_0;
Vishesh2b8e4792020-06-12 12:11:19 +0530656 } else if (does_level_match(width, height, init_framerate, 4096, 2176, 60.0,
657 2)) {
Hui Su8427ff22019-03-11 10:14:33 -0700658 level = SEQ_LEVEL_5_1;
Vishesh2b8e4792020-06-12 12:11:19 +0530659 } else if (does_level_match(width, height, init_framerate, 4096, 2176, 120.0,
660 2)) {
Hui Su8427ff22019-03-11 10:14:33 -0700661 level = SEQ_LEVEL_5_2;
Vishesh2b8e4792020-06-12 12:11:19 +0530662 } else if (does_level_match(width, height, init_framerate, 8192, 4352, 30.0,
663 2)) {
Hui Su8427ff22019-03-11 10:14:33 -0700664 level = SEQ_LEVEL_6_0;
Vishesh2b8e4792020-06-12 12:11:19 +0530665 } else if (does_level_match(width, height, init_framerate, 8192, 4352, 60.0,
666 2)) {
Todd Nguyenff4c8602019-11-25 13:20:21 -0800667 level = SEQ_LEVEL_6_1;
Vishesh2b8e4792020-06-12 12:11:19 +0530668 } else if (does_level_match(width, height, init_framerate, 8192, 4352, 120.0,
669 2)) {
Hui Su8427ff22019-03-11 10:14:33 -0700670 level = SEQ_LEVEL_6_2;
Debargha Mukherjee57498692018-05-11 13:29:31 -0700671 }
chiyotsaiaa33bbf2019-12-02 12:07:53 -0800672
Urvang Joshi450a9a22020-03-31 16:00:22 -0700673 SequenceHeader *const seq_params = &cm->seq_params;
Debargha Mukherjeeea675402018-05-10 16:10:41 -0700674 for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
Hui Su8427ff22019-03-11 10:14:33 -0700675 seq->seq_level_idx[i] = level;
Andrey Norkin26495512018-06-20 17:13:11 -0700676 // Set the maximum parameters for bitrate and buffer size for this profile,
677 // level, and tier
Urvang Joshi450a9a22020-03-31 16:00:22 -0700678 seq_params->op_params[i].bitrate = av1_max_level_bitrate(
Hui Su8427ff22019-03-11 10:14:33 -0700679 cm->seq_params.profile, seq->seq_level_idx[i], seq->tier[i]);
Andrey Norkinc7511de2018-06-22 12:31:06 -0700680 // Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass the
681 // check
Urvang Joshi450a9a22020-03-31 16:00:22 -0700682 if (seq_params->op_params[i].bitrate == 0)
Andrey Norkin26495512018-06-20 17:13:11 -0700683 aom_internal_error(
684 &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
685 "AV1 does not support this combination of profile, level, and tier.");
Andrey Norkinc7511de2018-06-22 12:31:06 -0700686 // Buffer size in bits/s is bitrate in bits/s * 1 s
Urvang Joshi450a9a22020-03-31 16:00:22 -0700687 seq_params->op_params[i].buffer_size = seq_params->op_params[i].bitrate;
Debargha Mukherjeeea675402018-05-10 16:10:41 -0700688 }
689}
690
Marco Paniconi2aa13c42020-06-01 11:18:38 -0700691void av1_init_seq_coding_tools(SequenceHeader *seq, AV1_COMMON *cm,
692 const AV1EncoderConfig *oxcf, int use_svc) {
Vishesh2b8e4792020-06-12 12:11:19 +0530693 const FrameDimensionCfg *const frm_dim_cfg = &oxcf->frm_dim_cfg;
694
Yaowu Xu2a9ac432019-08-06 14:21:17 -0700695 seq->still_picture = (oxcf->force_video_mode == 0) && (oxcf->limit == 1);
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700696 seq->reduced_still_picture_hdr = seq->still_picture;
Debargha Mukherjee9713ccb2018-04-08 19:09:17 -0700697 seq->reduced_still_picture_hdr &= !oxcf->full_still_picture_hdr;
kyslov94243382019-05-02 15:33:32 -0700698 seq->force_screen_content_tools = (oxcf->mode == REALTIME) ? 0 : 2;
Debargha Mukherjeeedd77252018-03-25 12:01:38 -0700699 seq->force_integer_mv = 2;
David Turnerebf96f42018-11-14 16:57:57 +0000700 seq->order_hint_info.enable_order_hint = oxcf->enable_order_hint;
David Turner936235c2018-11-28 13:42:01 +0000701 seq->frame_id_numbers_present_flag =
702 !(seq->still_picture && seq->reduced_still_picture_hdr) &&
Vishesh0481a782020-06-11 14:32:46 +0530703 !oxcf->tile_cfg.enable_large_scale_tile && oxcf->error_resilient_mode &&
704 !use_svc;
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700705 if (seq->still_picture && seq->reduced_still_picture_hdr) {
David Turnerebf96f42018-11-14 16:57:57 +0000706 seq->order_hint_info.enable_order_hint = 0;
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700707 seq->force_screen_content_tools = 2;
708 seq->force_integer_mv = 2;
709 }
David Turnerebf96f42018-11-14 16:57:57 +0000710 seq->order_hint_info.order_hint_bits_minus_1 =
711 seq->order_hint_info.enable_order_hint
712 ? DEFAULT_EXPLICIT_ORDER_HINT_BITS - 1
713 : -1;
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700714
Vishesh2b8e4792020-06-12 12:11:19 +0530715 seq->max_frame_width = frm_dim_cfg->forced_max_frame_width
716 ? frm_dim_cfg->forced_max_frame_width
717 : frm_dim_cfg->width;
718 seq->max_frame_height = frm_dim_cfg->forced_max_frame_height
719 ? frm_dim_cfg->forced_max_frame_height
720 : frm_dim_cfg->height;
David Turner760a2f42018-12-07 15:25:36 +0000721 seq->num_bits_width =
722 (seq->max_frame_width > 1) ? get_msb(seq->max_frame_width - 1) + 1 : 1;
723 seq->num_bits_height =
724 (seq->max_frame_height > 1) ? get_msb(seq->max_frame_height - 1) + 1 : 1;
725 assert(seq->num_bits_width <= 16);
726 assert(seq->num_bits_height <= 16);
727
728 seq->frame_id_length = FRAME_ID_LENGTH;
729 seq->delta_frame_id_length = DELTA_FRAME_ID_LENGTH;
730
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700731 seq->enable_dual_filter = oxcf->enable_dual_filter;
Vishesh8db8a202020-06-02 17:09:45 +0530732 seq->order_hint_info.enable_dist_wtd_comp =
733 oxcf->comp_type_cfg.enable_dist_wtd_comp;
Debargha Mukherjee7ac3eb12018-12-12 10:26:50 -0800734 seq->order_hint_info.enable_dist_wtd_comp &=
David Turnerebf96f42018-11-14 16:57:57 +0000735 seq->order_hint_info.enable_order_hint;
736 seq->order_hint_info.enable_ref_frame_mvs = oxcf->enable_ref_frame_mvs;
737 seq->order_hint_info.enable_ref_frame_mvs &=
738 seq->order_hint_info.enable_order_hint;
Vishesh0d279aa2020-06-03 15:56:56 +0530739 seq->enable_superres = oxcf->superres_cfg.enable_superres;
Debargha Mukherjeeedd77252018-03-25 12:01:38 -0700740 seq->enable_cdef = oxcf->enable_cdef;
741 seq->enable_restoration = oxcf->enable_restoration;
Vishesh015b4962020-06-15 14:19:55 +0530742 seq->enable_warped_motion = oxcf->motion_mode_cfg.enable_warped_motion;
Debargha Mukherjee16ea6ba2018-12-10 12:01:38 -0800743 seq->enable_interintra_compound = oxcf->enable_interintra_comp;
Vishesh8db8a202020-06-02 17:09:45 +0530744 seq->enable_masked_compound = oxcf->comp_type_cfg.enable_masked_comp;
Vishesh29649842020-06-01 18:18:36 +0530745 seq->enable_intra_edge_filter = oxcf->intra_mode_cfg.enable_intra_edge_filter;
746 seq->enable_filter_intra = oxcf->intra_mode_cfg.enable_filter_intra;
Debargha Mukherjee57498692018-05-11 13:29:31 -0700747
Vishesh2b8e4792020-06-12 12:11:19 +0530748 set_bitstream_level_tier(seq, cm, frm_dim_cfg->width, frm_dim_cfg->height,
749 oxcf->init_framerate);
Adrian Grangec56f6ec2018-05-31 14:19:32 -0700750
751 if (seq->operating_points_cnt_minus_1 == 0) {
752 seq->operating_point_idc[0] = 0;
753 } else {
Marco Paniconi6da983b2019-09-16 20:12:43 -0700754 // Set operating_point_idc[] such that the i=0 point corresponds to the
755 // highest quality operating point (all layers), and subsequent
756 // operarting points (i > 0) are lower quality corresponding to
757 // skip decoding enhancement layers (temporal first).
758 int i = 0;
759 assert(seq->operating_points_cnt_minus_1 ==
760 (int)(cm->number_spatial_layers * cm->number_temporal_layers - 1));
761 for (unsigned int sl = 0; sl < cm->number_spatial_layers; sl++) {
762 for (unsigned int tl = 0; tl < cm->number_temporal_layers; tl++) {
763 seq->operating_point_idc[i] =
764 (~(~0u << (cm->number_spatial_layers - sl)) << 8) |
765 ~(~0u << (cm->number_temporal_layers - tl));
766 i++;
767 }
768 }
Adrian Grangec56f6ec2018-05-31 14:19:32 -0700769 }
Debargha Mukherjeeedd77252018-03-25 12:01:38 -0700770}
771
Yaowu Xuf883b422016-08-30 14:01:10 -0700772static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
773 AV1_COMMON *const cm = &cpi->common;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700774 SequenceHeader *const seq_params = &cm->seq_params;
Jayasanker J0b1dd292020-04-09 15:47:25 +0530775 ResizePendingParams *resize_pending_params = &cpi->resize_pending_params;
Vishesha9082242020-06-17 18:26:09 +0530776 const DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
Vishesh52fdeae2020-06-24 14:37:00 +0530777 const ColorCfg *const color_cfg = &oxcf->color_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700778 cpi->oxcf = *oxcf;
779 cpi->framerate = oxcf->init_framerate;
780
Urvang Joshi450a9a22020-03-31 16:00:22 -0700781 seq_params->profile = oxcf->profile;
782 seq_params->bit_depth = oxcf->bit_depth;
783 seq_params->use_highbitdepth = oxcf->use_highbitdepth;
Vishesh52fdeae2020-06-24 14:37:00 +0530784 seq_params->color_primaries = color_cfg->color_primaries;
785 seq_params->transfer_characteristics = color_cfg->transfer_characteristics;
786 seq_params->matrix_coefficients = color_cfg->matrix_coefficients;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700787 seq_params->monochrome = oxcf->monochrome;
788 seq_params->chroma_sample_position = oxcf->chroma_sample_position;
Vishesh52fdeae2020-06-24 14:37:00 +0530789 seq_params->color_range = color_cfg->color_range;
Vishesha9082242020-06-17 18:26:09 +0530790 seq_params->timing_info_present = dec_model_cfg->timing_info_present;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700791 seq_params->timing_info.num_units_in_display_tick =
Vishesha9082242020-06-17 18:26:09 +0530792 dec_model_cfg->timing_info.num_units_in_display_tick;
793 seq_params->timing_info.time_scale = dec_model_cfg->timing_info.time_scale;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700794 seq_params->timing_info.equal_picture_interval =
Vishesha9082242020-06-17 18:26:09 +0530795 dec_model_cfg->timing_info.equal_picture_interval;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700796 seq_params->timing_info.num_ticks_per_picture =
Vishesha9082242020-06-17 18:26:09 +0530797 dec_model_cfg->timing_info.num_ticks_per_picture;
Andrey Norkin795ba872018-03-06 13:24:14 -0800798
Urvang Joshi450a9a22020-03-31 16:00:22 -0700799 seq_params->display_model_info_present_flag =
Vishesha9082242020-06-17 18:26:09 +0530800 dec_model_cfg->display_model_info_present_flag;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700801 seq_params->decoder_model_info_present_flag =
Vishesha9082242020-06-17 18:26:09 +0530802 dec_model_cfg->decoder_model_info_present_flag;
803 if (dec_model_cfg->decoder_model_info_present_flag) {
Andrey Norkin26495512018-06-20 17:13:11 -0700804 // set the decoder model parameters in schedule mode
Urvang Joshi450a9a22020-03-31 16:00:22 -0700805 seq_params->decoder_model_info.num_units_in_decoding_tick =
Vishesha9082242020-06-17 18:26:09 +0530806 dec_model_cfg->num_units_in_decoding_tick;
Wan-Teh Changf64b3bc2018-07-02 09:42:39 -0700807 cm->buffer_removal_time_present = 1;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700808 av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
809 av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
810 } else if (seq_params->timing_info_present &&
811 seq_params->timing_info.equal_picture_interval &&
812 !seq_params->decoder_model_info_present_flag) {
Andrey Norkin26495512018-06-20 17:13:11 -0700813 // set the decoder model parameters in resource availability mode
Urvang Joshi450a9a22020-03-31 16:00:22 -0700814 av1_set_resource_availability_parameters(&seq_params->op_params[0]);
Andrey Norkinc7511de2018-06-22 12:31:06 -0700815 } else {
Urvang Joshi450a9a22020-03-31 16:00:22 -0700816 seq_params->op_params[0].initial_display_delay =
Andrey Norkinc7511de2018-06-22 12:31:06 -0700817 10; // Default value (not signaled)
Andrey Norkin795ba872018-03-06 13:24:14 -0800818 }
Andrey Norkinc7511de2018-06-22 12:31:06 -0700819
Urvang Joshi450a9a22020-03-31 16:00:22 -0700820 if (seq_params->monochrome) {
821 seq_params->subsampling_x = 1;
822 seq_params->subsampling_y = 1;
823 } else if (seq_params->color_primaries == AOM_CICP_CP_BT_709 &&
824 seq_params->transfer_characteristics == AOM_CICP_TC_SRGB &&
825 seq_params->matrix_coefficients == AOM_CICP_MC_IDENTITY) {
826 seq_params->subsampling_x = 0;
827 seq_params->subsampling_y = 0;
Tom Fineganf8d6a162018-08-21 10:47:55 -0700828 } else {
Urvang Joshi450a9a22020-03-31 16:00:22 -0700829 if (seq_params->profile == 0) {
830 seq_params->subsampling_x = 1;
831 seq_params->subsampling_y = 1;
832 } else if (seq_params->profile == 1) {
833 seq_params->subsampling_x = 0;
834 seq_params->subsampling_y = 0;
Tom Fineganf8d6a162018-08-21 10:47:55 -0700835 } else {
Urvang Joshi450a9a22020-03-31 16:00:22 -0700836 if (seq_params->bit_depth == AOM_BITS_12) {
837 seq_params->subsampling_x = oxcf->chroma_subsampling_x;
838 seq_params->subsampling_y = oxcf->chroma_subsampling_y;
Tom Fineganf8d6a162018-08-21 10:47:55 -0700839 } else {
Urvang Joshi450a9a22020-03-31 16:00:22 -0700840 seq_params->subsampling_x = 1;
841 seq_params->subsampling_y = 0;
Tom Fineganf8d6a162018-08-21 10:47:55 -0700842 }
843 }
Tom Finegan02b2a842018-08-24 13:50:00 -0700844 }
845
Vishesh2b8e4792020-06-12 12:11:19 +0530846 cm->width = oxcf->frm_dim_cfg.width;
847 cm->height = oxcf->frm_dim_cfg.height;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700848 set_sb_size(seq_params,
Imdad Sardharwalla4ec84ab2018-02-06 12:20:18 +0000849 select_sb_size(cpi)); // set sb size before allocations
Cheng Chen46f30c72017-09-07 11:13:33 -0700850 alloc_compressor_data(cpi);
Yaowu Xuc7119a72018-03-29 09:59:37 -0700851
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800852 update_film_grain_parameters(cpi, oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700853
854 // Single thread case: use counts in common.
Yue Chencc6a6ef2018-05-21 16:21:05 -0700855 cpi->td.counts = &cpi->counts;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700856
Marco Paniconi882c5ad2019-09-30 21:32:29 -0700857 // Set init SVC parameters.
Marco Paniconi67142112019-07-24 15:00:31 -0700858 cpi->use_svc = 0;
Marco Paniconid8574e32019-08-04 21:30:12 -0700859 cpi->svc.external_ref_frame_config = 0;
860 cpi->svc.non_reference_frame = 0;
Marco Paniconi57247a82020-04-13 09:19:07 -0700861 cpi->svc.number_spatial_layers = 1;
862 cpi->svc.number_temporal_layers = 1;
Marco Paniconi67142112019-07-24 15:00:31 -0700863 cm->number_spatial_layers = 1;
864 cm->number_temporal_layers = 1;
Marco Paniconi882c5ad2019-09-30 21:32:29 -0700865 cm->spatial_layer_id = 0;
866 cm->temporal_layer_id = 0;
Marco Paniconi67142112019-07-24 15:00:31 -0700867
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868 // change includes all joint functionality
Yaowu Xuf883b422016-08-30 14:01:10 -0700869 av1_change_config(cpi, oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700870
Yaowu Xuc27fc142016-08-22 16:08:15 -0700871 cpi->ref_frame_flags = 0;
872
Debargha Mukherjeeccb27262017-09-25 14:19:46 -0700873 // Reset resize pending flags
Jayasanker J0b1dd292020-04-09 15:47:25 +0530874 resize_pending_params->width = 0;
875 resize_pending_params->height = 0;
Debargha Mukherjeeccb27262017-09-25 14:19:46 -0700876
Vishesh2260a592020-04-06 15:34:51 +0530877 init_buffer_indices(&cpi->force_intpel_info, cm->remapped_ref_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700878}
879
Yaowu Xuf883b422016-08-30 14:01:10 -0700880void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
881 AV1_COMMON *const cm = &cpi->common;
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700882 SequenceHeader *const seq_params = &cm->seq_params;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700883 RATE_CONTROL *const rc = &cpi->rc;
hui sud9a812b2017-07-06 14:34:37 -0700884 MACROBLOCK *const x = &cpi->td.mb;
Vishesh8ac928b2020-04-01 02:36:35 +0530885 AV1LevelParams *const level_params = &cpi->level_params;
Jayasanker J44fdab72020-04-13 20:34:38 +0530886 InitialDimensions *const initial_dimensions = &cpi->initial_dimensions;
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530887 RefreshFrameFlagsInfo *const refresh_frame_flags = &cpi->refresh_frame;
Vishesh2b8e4792020-06-12 12:11:19 +0530888 const FrameDimensionCfg *const frm_dim_cfg = &cpi->oxcf.frm_dim_cfg;
Vishesha9082242020-06-17 18:26:09 +0530889 const DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
Vishesh52fdeae2020-06-24 14:37:00 +0530890 const ColorCfg *const color_cfg = &oxcf->color_cfg;
Vishesha9082242020-06-17 18:26:09 +0530891
Mufaddal Chakera48e16492020-05-04 16:07:18 +0530892 // in case of LAP, lag in frames is set according to number of lap buffers
893 // calculated at init time. This stores and restores LAP's lag in frames to
894 // prevent override by new cfg.
895 int lap_lag_in_frames = -1;
896 if (cpi->lap_enabled && cpi->compressor_stage == LAP_STAGE) {
Vishesh5b50e6d2020-06-10 19:20:07 +0530897 lap_lag_in_frames = cpi->oxcf.gf_cfg.lag_in_frames;
Mufaddal Chakera48e16492020-05-04 16:07:18 +0530898 }
899
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700900 if (seq_params->profile != oxcf->profile) seq_params->profile = oxcf->profile;
901 seq_params->bit_depth = oxcf->bit_depth;
Vishesh52fdeae2020-06-24 14:37:00 +0530902 seq_params->color_primaries = color_cfg->color_primaries;
903 seq_params->transfer_characteristics = color_cfg->transfer_characteristics;
904 seq_params->matrix_coefficients = color_cfg->matrix_coefficients;
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700905 seq_params->monochrome = oxcf->monochrome;
906 seq_params->chroma_sample_position = oxcf->chroma_sample_position;
Vishesh52fdeae2020-06-24 14:37:00 +0530907 seq_params->color_range = color_cfg->color_range;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700908
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700909 assert(IMPLIES(seq_params->profile <= PROFILE_1,
910 seq_params->bit_depth <= AOM_BITS_10));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700911
Vishesha9082242020-06-17 18:26:09 +0530912 seq_params->timing_info_present = dec_model_cfg->timing_info_present;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700913 seq_params->timing_info.num_units_in_display_tick =
Vishesha9082242020-06-17 18:26:09 +0530914 dec_model_cfg->timing_info.num_units_in_display_tick;
915 seq_params->timing_info.time_scale = dec_model_cfg->timing_info.time_scale;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700916 seq_params->timing_info.equal_picture_interval =
Vishesha9082242020-06-17 18:26:09 +0530917 dec_model_cfg->timing_info.equal_picture_interval;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700918 seq_params->timing_info.num_ticks_per_picture =
Vishesha9082242020-06-17 18:26:09 +0530919 dec_model_cfg->timing_info.num_ticks_per_picture;
Andrey Norkin795ba872018-03-06 13:24:14 -0800920
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700921 seq_params->display_model_info_present_flag =
Vishesha9082242020-06-17 18:26:09 +0530922 dec_model_cfg->display_model_info_present_flag;
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700923 seq_params->decoder_model_info_present_flag =
Vishesha9082242020-06-17 18:26:09 +0530924 dec_model_cfg->decoder_model_info_present_flag;
925 if (dec_model_cfg->decoder_model_info_present_flag) {
Andrey Norkin26495512018-06-20 17:13:11 -0700926 // set the decoder model parameters in schedule mode
Urvang Joshi450a9a22020-03-31 16:00:22 -0700927 seq_params->decoder_model_info.num_units_in_decoding_tick =
Vishesha9082242020-06-17 18:26:09 +0530928 dec_model_cfg->num_units_in_decoding_tick;
Wan-Teh Changf64b3bc2018-07-02 09:42:39 -0700929 cm->buffer_removal_time_present = 1;
Urvang Joshi450a9a22020-03-31 16:00:22 -0700930 av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
931 av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
932 } else if (seq_params->timing_info_present &&
933 seq_params->timing_info.equal_picture_interval &&
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700934 !seq_params->decoder_model_info_present_flag) {
Andrey Norkin26495512018-06-20 17:13:11 -0700935 // set the decoder model parameters in resource availability mode
Urvang Joshi450a9a22020-03-31 16:00:22 -0700936 av1_set_resource_availability_parameters(&seq_params->op_params[0]);
Andrey Norkinc7511de2018-06-22 12:31:06 -0700937 } else {
Urvang Joshi450a9a22020-03-31 16:00:22 -0700938 seq_params->op_params[0].initial_display_delay =
Andrey Norkinc7511de2018-06-22 12:31:06 -0700939 10; // Default value (not signaled)
Andrey Norkin795ba872018-03-06 13:24:14 -0800940 }
Andrey Norkin28e9ce22018-01-08 10:11:21 -0800941
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800942 update_film_grain_parameters(cpi, oxcf);
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800943
Yaowu Xuc27fc142016-08-22 16:08:15 -0700944 cpi->oxcf = *oxcf;
Vishesh0d279aa2020-06-03 15:56:56 +0530945 cpi->superres_mode = oxcf->superres_cfg.superres_mode; // default
Urvang Joshi20cf30e2018-07-19 02:33:58 -0700946 x->e_mbd.bd = (int)seq_params->bit_depth;
hui sud9a812b2017-07-06 14:34:37 -0700947 x->e_mbd.global_motion = cm->global_motion;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948
Vishesh8ac928b2020-04-01 02:36:35 +0530949 memcpy(level_params->target_seq_level_idx, cpi->oxcf.target_seq_level_idx,
950 sizeof(level_params->target_seq_level_idx));
951 level_params->keep_level_stats = 0;
Wan-Teh Changbcacb322019-09-11 14:50:20 -0700952 for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
Vishesh8ac928b2020-04-01 02:36:35 +0530953 if (level_params->target_seq_level_idx[i] <= SEQ_LEVELS) {
954 level_params->keep_level_stats |= 1u << i;
955 if (!level_params->level_info[i]) {
956 CHECK_MEM_ERROR(cm, level_params->level_info[i],
957 aom_calloc(1, sizeof(*level_params->level_info[i])));
Wan-Teh Changbcacb322019-09-11 14:50:20 -0700958 }
959 }
960 }
961
962 // TODO(huisu@): level targeting currently only works for the 0th operating
963 // point, so scalable coding is not supported yet.
Vishesh8ac928b2020-04-01 02:36:35 +0530964 if (level_params->target_seq_level_idx[0] < SEQ_LEVELS) {
Wan-Teh Changbcacb322019-09-11 14:50:20 -0700965 // Adjust encoder config in order to meet target level.
Vishesh8ac928b2020-04-01 02:36:35 +0530966 config_target_level(cpi, level_params->target_seq_level_idx[0],
967 seq_params->tier[0]);
Wan-Teh Changbcacb322019-09-11 14:50:20 -0700968 }
969
Vishesh39e74092020-06-16 17:13:48 +0530970 if ((has_no_stats_stage(cpi)) && (oxcf->rc_cfg.mode == AOM_Q)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700971 rc->baseline_gf_interval = FIXED_GF_INTERVAL;
972 } else {
973 rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
974 }
975
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530976 refresh_frame_flags->golden_frame = false;
977 refresh_frame_flags->bwd_ref_frame = false;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700978
Urvang Joshi6237b882020-03-26 15:02:26 -0700979 cm->features.refresh_frame_context = (oxcf->frame_parallel_decoding_mode)
980 ? REFRESH_FRAME_CONTEXT_DISABLED
981 : REFRESH_FRAME_CONTEXT_BACKWARD;
Vishesh0481a782020-06-11 14:32:46 +0530982 if (oxcf->tile_cfg.enable_large_scale_tile)
Urvang Joshi6237b882020-03-26 15:02:26 -0700983 cm->features.refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
Rupert Swarbrick84b05ac2017-10-27 18:10:53 +0100984
Alex Converse74ad0912017-07-18 10:22:58 -0700985 if (x->palette_buffer == NULL) {
hui sud9a812b2017-07-06 14:34:37 -0700986 CHECK_MEM_ERROR(cm, x->palette_buffer,
987 aom_memalign(16, sizeof(*x->palette_buffer)));
988 }
Urvang Joshi0a4cfad2018-09-07 11:10:39 -0700989
Hui Su38711e72019-06-11 10:49:47 -0700990 if (x->comp_rd_buffer.pred0 == NULL) {
Satish Kumar Sumand3caa0d2020-06-16 14:02:50 +0530991 alloc_compound_type_rd_buffers(cm, &x->comp_rd_buffer);
Hui Su38711e72019-06-11 10:49:47 -0700992 }
993
Urvang Joshi0a4cfad2018-09-07 11:10:39 -0700994 if (x->tmp_conv_dst == NULL) {
995 CHECK_MEM_ERROR(
996 cm, x->tmp_conv_dst,
997 aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE * sizeof(*x->tmp_conv_dst)));
Urvang Joshie58f6ec2018-09-10 15:10:12 -0700998 x->e_mbd.tmp_conv_dst = x->tmp_conv_dst;
Urvang Joshi0a4cfad2018-09-07 11:10:39 -0700999 }
1000 for (int i = 0; i < 2; ++i) {
chiyotsai2a897eb2020-04-28 19:22:13 -07001001 if (x->tmp_pred_bufs[i] == NULL) {
1002 CHECK_MEM_ERROR(cm, x->tmp_pred_bufs[i],
wenyao.liu22d8ab32018-10-16 09:11:29 +08001003 aom_memalign(32, 2 * MAX_MB_PLANE * MAX_SB_SQUARE *
chiyotsai2a897eb2020-04-28 19:22:13 -07001004 sizeof(*x->tmp_pred_bufs[i])));
1005 x->e_mbd.tmp_obmc_bufs[i] = x->tmp_pred_bufs[i];
Urvang Joshi0a4cfad2018-09-07 11:10:39 -07001006 }
1007 }
1008
Marco Paniconi177b8c32020-01-26 20:37:29 -08001009 av1_reset_segment_features(cm);
Fyodor Kyslov64aaa092020-01-24 11:44:24 -08001010
chiyotsaic666b1f2019-12-20 10:44:58 -08001011 av1_set_high_precision_mv(cpi, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001012
Yaowu Xuc27fc142016-08-22 16:08:15 -07001013 set_rc_buffer_sizes(rc, &cpi->oxcf);
1014
1015 // Under a configuration change, where maximum_buffer_size may change,
1016 // keep buffer level clipped to the maximum allowed buffer size.
Yaowu Xuf883b422016-08-30 14:01:10 -07001017 rc->bits_off_target = AOMMIN(rc->bits_off_target, rc->maximum_buffer_size);
1018 rc->buffer_level = AOMMIN(rc->buffer_level, rc->maximum_buffer_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001019
1020 // Set up frame rate and related parameters rate control values.
Yaowu Xuf883b422016-08-30 14:01:10 -07001021 av1_new_framerate(cpi, cpi->framerate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001022
1023 // Set absolute upper and lower quality limits
Vishesh39e74092020-06-16 17:13:48 +05301024 rc->worst_quality = cpi->oxcf.rc_cfg.worst_allowed_q;
1025 rc->best_quality = cpi->oxcf.rc_cfg.best_allowed_q;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001026
Urvang Joshi6237b882020-03-26 15:02:26 -07001027 cm->features.interp_filter =
Vishesh0481a782020-06-11 14:32:46 +05301028 oxcf->tile_cfg.enable_large_scale_tile ? EIGHTTAP_REGULAR : SWITCHABLE;
Urvang Joshi6237b882020-03-26 15:02:26 -07001029 cm->features.switchable_motion_mode = 1;
Yue Chen5380cb52018-02-23 15:33:21 -08001030
Vishesh2b8e4792020-06-12 12:11:19 +05301031 if (frm_dim_cfg->render_width > 0 && frm_dim_cfg->render_height > 0) {
1032 cm->render_width = frm_dim_cfg->render_width;
1033 cm->render_height = frm_dim_cfg->render_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001034 } else {
Vishesh2b8e4792020-06-12 12:11:19 +05301035 cm->render_width = frm_dim_cfg->width;
1036 cm->render_height = frm_dim_cfg->height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001037 }
Vishesh2b8e4792020-06-12 12:11:19 +05301038 cm->width = frm_dim_cfg->width;
1039 cm->height = frm_dim_cfg->height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001040
Urvang Joshi20cf30e2018-07-19 02:33:58 -07001041 int sb_size = seq_params->sb_size;
Urvang Joshie4530f82018-01-09 11:43:37 -08001042 // Superblock size should not be updated after the first key frame.
1043 if (!cpi->seq_params_locked) {
1044 set_sb_size(&cm->seq_params, select_sb_size(cpi));
Hui Sud909c2c2019-03-08 11:51:14 -08001045 for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i)
1046 seq_params->tier[i] = (oxcf->tier_mask >> i) & 1;
Urvang Joshie4530f82018-01-09 11:43:37 -08001047 }
Dominic Symes917d6c02017-10-11 18:00:52 +02001048
Jayasanker J44fdab72020-04-13 20:34:38 +05301049 if (initial_dimensions->width || sb_size != seq_params->sb_size) {
1050 if (cm->width > initial_dimensions->width ||
1051 cm->height > initial_dimensions->height ||
Urvang Joshi20cf30e2018-07-19 02:33:58 -07001052 seq_params->sb_size != sb_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001053 av1_free_context_buffers(cm);
Yue Cheneb628982019-08-29 15:17:13 -07001054 av1_free_shared_coeff_buffer(&cpi->td.shared_coeff_buf);
1055 av1_free_sms_tree(&cpi->td);
Mufaddal Chakera6c3b6de2020-04-29 12:27:42 +05301056 av1_free_pmc(cpi->td.firstpass_ctx, av1_num_planes(cm));
1057 cpi->td.firstpass_ctx = NULL;
Cheng Chen46f30c72017-09-07 11:13:33 -07001058 alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001059 realloc_segmentation_maps(cpi);
Jayasanker J44fdab72020-04-13 20:34:38 +05301060 initial_dimensions->width = initial_dimensions->height = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001061 }
1062 }
1063 update_frame_size(cpi);
1064
Yaowu Xuc27fc142016-08-22 16:08:15 -07001065 rc->is_src_frame_alt_ref = 0;
1066
Vishesh0481a782020-06-11 14:32:46 +05301067 set_tile_info(cm, &cpi->oxcf.tile_cfg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001068
Marco Paniconid8574e32019-08-04 21:30:12 -07001069 if (!cpi->svc.external_ref_frame_config)
Vishesh38c05d72020-04-14 12:19:14 +05301070 cpi->ext_flags.refresh_frame.update_pending = 0;
Vishesha195ca32020-04-07 18:46:20 +05301071 cpi->ext_flags.refresh_frame_context_pending = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001072
Jerome Jiangfa1d1732019-08-06 10:31:20 -07001073#if CONFIG_AV1_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001074 highbd_set_var_fns(cpi);
Jerome Jiangfa1d1732019-08-06 10:31:20 -07001075#endif
Imdad Sardharwallabf2cc012018-02-09 17:32:10 +00001076
Debargha Mukherjeeedd77252018-03-25 12:01:38 -07001077 // Init sequence level coding tools
Debargha Mukherjeef2e5bb32018-03-26 14:35:24 -07001078 // This should not be called after the first key frame.
1079 if (!cpi->seq_params_locked) {
Urvang Joshi20cf30e2018-07-19 02:33:58 -07001080 seq_params->operating_points_cnt_minus_1 =
Marco Paniconi6da983b2019-09-16 20:12:43 -07001081 (cm->number_spatial_layers > 1 || cm->number_temporal_layers > 1)
1082 ? cm->number_spatial_layers * cm->number_temporal_layers - 1
1083 : 0;
Marco Paniconi2aa13c42020-06-01 11:18:38 -07001084 av1_init_seq_coding_tools(&cm->seq_params, cm, oxcf, cpi->use_svc);
Debargha Mukherjeef2e5bb32018-03-26 14:35:24 -07001085 }
Marco Paniconi5b1e4732019-08-08 18:57:53 -07001086
1087 if (cpi->use_svc)
1088 av1_update_layer_context_change_config(cpi, oxcf->target_bandwidth);
Mufaddal Chakera48e16492020-05-04 16:07:18 +05301089
1090 // restore the value of lag_in_frame for LAP stage.
1091 if (lap_lag_in_frames != -1) {
Vishesh5b50e6d2020-06-10 19:20:07 +05301092 cpi->oxcf.gf_cfg.lag_in_frames = lap_lag_in_frames;
Mufaddal Chakera48e16492020-05-04 16:07:18 +05301093 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001094}
1095
Urvang Joshi31a7aa52020-03-31 13:09:13 -07001096static INLINE void init_frame_info(FRAME_INFO *frame_info,
1097 const AV1_COMMON *const cm) {
1098 const CommonModeInfoParams *const mi_params = &cm->mi_params;
1099 const SequenceHeader *const seq_params = &cm->seq_params;
1100 frame_info->frame_width = cm->width;
1101 frame_info->frame_height = cm->height;
1102 frame_info->mi_cols = mi_params->mi_cols;
1103 frame_info->mi_rows = mi_params->mi_rows;
1104 frame_info->mb_cols = mi_params->mb_cols;
1105 frame_info->mb_rows = mi_params->mb_rows;
1106 frame_info->num_mbs = mi_params->MBs;
1107 frame_info->bit_depth = seq_params->bit_depth;
1108 frame_info->subsampling_x = seq_params->subsampling_x;
1109 frame_info->subsampling_y = seq_params->subsampling_y;
1110}
1111
Aasaipriyabd659e42019-12-13 16:12:13 +05301112AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf, BufferPool *const pool,
Mufaddal Chakera5517b282019-12-13 16:39:56 +05301113 FIRSTPASS_STATS *frame_stats_buf,
Akshata Jadhava49be172019-12-18 00:03:53 +05301114 COMPRESSOR_STAGE stage, int num_lap_buffers,
Mufaddal Chakera412efe22020-01-17 14:35:01 +05301115 int lap_lag_in_frames,
Akshata Jadhava49be172019-12-18 00:03:53 +05301116 STATS_BUFFER_CTX *stats_buf_context) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001117 AV1_COMP *volatile const cpi = aom_memalign(32, sizeof(AV1_COMP));
1118 AV1_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001119
1120 if (!cm) return NULL;
1121
Yaowu Xuf883b422016-08-30 14:01:10 -07001122 av1_zero(*cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001123
Wan-Teh Changa2fad3e2018-07-19 16:55:19 -07001124 // The jmp_buf is valid only for the duration of the function that calls
1125 // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
1126 // before it returns.
Yaowu Xuc27fc142016-08-22 16:08:15 -07001127 if (setjmp(cm->error.jmp)) {
1128 cm->error.setjmp = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07001129 av1_remove_compressor(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130 return 0;
1131 }
1132
1133 cm->error.setjmp = 1;
Mufaddal Chakeraed7b1622020-04-06 12:30:23 +05301134 cpi->lap_enabled = num_lap_buffers > 0;
1135 cpi->compressor_stage = stage;
chiyotsaia7091f12019-08-09 16:48:27 -07001136
Urvang Joshi9dc909d2020-03-23 16:07:02 -07001137 CommonModeInfoParams *const mi_params = &cm->mi_params;
Urvang Joshi9dc909d2020-03-23 16:07:02 -07001138 mi_params->free_mi = enc_free_mi;
1139 mi_params->setup_mi = enc_setup_mi;
Mufaddal Chakeraed7b1622020-04-06 12:30:23 +05301140 mi_params->set_mb_mi = (oxcf->pass == 1 || cpi->compressor_stage == LAP_STAGE)
1141 ? stat_stage_set_mb_mi
1142 : enc_set_mb_mi;
Urvang Joshi9dc909d2020-03-23 16:07:02 -07001143
1144 mi_params->mi_alloc_bsize = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001145
Angie Chianga5d96c42016-10-21 16:16:56 -07001146 CHECK_MEM_ERROR(cm, cm->fc,
1147 (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
David Turner1bcefb32018-11-19 17:54:00 +00001148 CHECK_MEM_ERROR(
1149 cm, cm->default_frame_context,
1150 (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->default_frame_context)));
Angie Chianga5d96c42016-10-21 16:16:56 -07001151 memset(cm->fc, 0, sizeof(*cm->fc));
David Turner1bcefb32018-11-19 17:54:00 +00001152 memset(cm->default_frame_context, 0, sizeof(*cm->default_frame_context));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153
Yaowu Xuc27fc142016-08-22 16:08:15 -07001154 cpi->common.buffer_pool = pool;
1155
Mufaddal Chakera7b5265f2020-03-27 10:32:34 +05301156 init_config(cpi, oxcf);
Mufaddal Chakera11f284a2019-12-19 11:38:46 +05301157 if (cpi->compressor_stage == LAP_STAGE) {
Vishesh5b50e6d2020-06-10 19:20:07 +05301158 cpi->oxcf.gf_cfg.lag_in_frames = lap_lag_in_frames;
Mufaddal Chakera11f284a2019-12-19 11:38:46 +05301159 }
Mufaddal Chakeraac828682019-12-13 16:31:42 +05301160
Yaowu Xuf883b422016-08-30 14:01:10 -07001161 av1_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001162
Aasaipriya196c58a2020-04-23 19:05:45 +05301163 // For two pass and lag_in_frames > 33 in LAP.
1164 cpi->rc.enable_scenecut_detection = ENABLE_SCENECUT_MODE_2;
1165 if (cpi->lap_enabled) {
1166 if ((num_lap_buffers <
1167 (MAX_GF_LENGTH_LAP + SCENE_CUT_KEY_TEST_INTERVAL + 1)) &&
1168 num_lap_buffers >= (MAX_GF_LENGTH_LAP + 3)) {
1169 /*
1170 * For lag in frames >= 19 and <33, enable scenecut
1171 * with limited future frame prediction.
1172 */
1173 cpi->rc.enable_scenecut_detection = ENABLE_SCENECUT_MODE_1;
1174 } else if (num_lap_buffers < (MAX_GF_LENGTH_LAP + 3)) {
1175 // Disable scenecut when lag_in_frames < 19.
1176 cpi->rc.enable_scenecut_detection = DISABLE_SCENECUT;
1177 }
1178 }
Jingning Han17af7742019-09-17 16:58:03 -07001179 init_frame_info(&cpi->frame_info, cm);
1180
David Turnerd2a592e2018-11-16 14:59:31 +00001181 cm->current_frame.frame_number = 0;
David Turnera4c96252019-01-11 16:36:39 +00001182 cm->current_frame_id = -1;
Debargha Mukherjeef2e5bb32018-03-26 14:35:24 -07001183 cpi->seq_params_locked = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001184 cpi->partition_search_skippable_frame = 0;
1185 cpi->tile_data = NULL;
David Turnere7ebf902018-12-04 14:04:55 +00001186 cpi->last_show_frame_buf = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001187 realloc_segmentation_maps(cpi);
1188
Jayasanker J24cb9bc2020-04-15 13:43:10 +05301189 cpi->refresh_frame.alt_ref_frame = false;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001190
1191 cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
1192#if CONFIG_INTERNAL_STATS
1193 cpi->b_calculate_blockiness = 1;
1194 cpi->b_calculate_consistency = 1;
1195 cpi->total_inconsistency = 0;
1196 cpi->psnr.worst = 100.0;
1197 cpi->worst_ssim = 100.0;
1198
1199 cpi->count = 0;
1200 cpi->bytes = 0;
Debargha Mukherjee0857e662019-01-04 16:22:09 -08001201#if CONFIG_SPEED_STATS
1202 cpi->tx_search_count = 0;
1203#endif // CONFIG_SPEED_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07001204
1205 if (cpi->b_calculate_psnr) {
1206 cpi->total_sq_error = 0;
1207 cpi->total_samples = 0;
1208 cpi->tot_recode_hits = 0;
1209 cpi->summed_quality = 0;
1210 cpi->summed_weights = 0;
1211 }
1212
1213 cpi->fastssim.worst = 100.0;
1214 cpi->psnrhvs.worst = 100.0;
1215
1216 if (cpi->b_calculate_blockiness) {
1217 cpi->total_blockiness = 0;
1218 cpi->worst_blockiness = 0.0;
1219 }
1220
1221 if (cpi->b_calculate_consistency) {
Urvang Joshi9dc909d2020-03-23 16:07:02 -07001222 CHECK_MEM_ERROR(
1223 cm, cpi->ssim_vars,
1224 aom_malloc(sizeof(*cpi->ssim_vars) * 4 * cpi->common.mi_params.mi_rows *
1225 cpi->common.mi_params.mi_cols));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001226 cpi->worst_consistency = 100.0;
1227 }
1228#endif
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08001229#if CONFIG_ENTROPY_STATS
1230 av1_zero(aggregate_fc);
1231#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07001232
Deepa K Gfb89ce02020-04-06 13:34:42 +05301233 cpi->time_stamps.first_ever = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001234
Yaowu Xuc27fc142016-08-22 16:08:15 -07001235#ifdef OUTPUT_YUV_REC
1236 yuv_rec_file = fopen("rec.yuv", "wb");
1237#endif
1238
Mufaddal Chakera5517b282019-12-13 16:39:56 +05301239 assert(MAX_LAP_BUFFERS >= MAX_LAG_BUFFERS);
Akshata Jadhav4be65112019-12-18 00:26:25 +05301240 int size = get_stats_buf_size(num_lap_buffers, MAX_LAG_BUFFERS);
1241 for (int i = 0; i < size; i++)
Aasaipriyabd659e42019-12-13 16:12:13 +05301242 cpi->twopass.frame_stats_arr[i] = &frame_stats_buf[i];
1243
Akshata Jadhava49be172019-12-18 00:03:53 +05301244 cpi->twopass.stats_buf_ctx = stats_buf_context;
1245 cpi->twopass.stats_in = cpi->twopass.stats_buf_ctx->stats_in_start;
1246
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001247#if !CONFIG_REALTIME_ONLY
Aasaipriyaeb417c12020-04-07 12:08:24 +05301248 if (is_stat_consumption_stage(cpi)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001249 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
Vishesh7e310402020-06-18 14:24:16 +05301250 const int packets = (int)(oxcf->two_pass_cfg.stats_in.sz / packet_sz);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001251
Akshata Jadhav1fddf7f2019-12-18 00:49:25 +05301252 if (!cpi->lap_enabled) {
1253 /*Re-initialize to stats buffer, populated by application in the case of
1254 * two pass*/
Vishesh7e310402020-06-18 14:24:16 +05301255 cpi->twopass.stats_buf_ctx->stats_in_start =
1256 oxcf->two_pass_cfg.stats_in.buf;
Akshata Jadhav1fddf7f2019-12-18 00:49:25 +05301257 cpi->twopass.stats_in = cpi->twopass.stats_buf_ctx->stats_in_start;
1258 cpi->twopass.stats_buf_ctx->stats_in_end =
1259 &cpi->twopass.stats_buf_ctx->stats_in_start[packets - 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001260
Mufaddal Chakera74c9cbe2020-01-17 16:44:59 +05301261 av1_init_second_pass(cpi);
1262 } else {
1263 av1_init_single_pass_lap(cpi);
1264 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001265 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001266#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001267
Remya0cce44c2019-08-16 11:57:24 +05301268 int sb_mi_size = av1_get_sb_mi_size(cm);
1269
Satish Kumar Sumand3caa0d2020-06-16 14:02:50 +05301270 alloc_obmc_buffers(&cpi->td.mb.obmc_buffer, cm);
Jingning Hand064cf02017-06-01 10:00:39 -07001271
Ravi Chaudhary5d970f42018-09-25 11:25:32 +05301272 CHECK_MEM_ERROR(
1273 cm, cpi->td.mb.inter_modes_info,
1274 (InterModesInfo *)aom_malloc(sizeof(*cpi->td.mb.inter_modes_info)));
Ravi Chaudhary5d970f42018-09-25 11:25:32 +05301275
Ravi Chaudhary783d6a32018-08-28 18:21:02 +05301276 for (int x = 0; x < 2; x++)
1277 for (int y = 0; y < 2; y++)
1278 CHECK_MEM_ERROR(
chiyotsai82f36c92020-04-09 16:18:02 -07001279 cm, cpi->td.mb.intrabc_hash_info.hash_value_buffer[x][y],
1280 (uint32_t *)aom_malloc(
1281 AOM_BUFFER_SIZE_FOR_BLOCK_HASH *
1282 sizeof(*cpi->td.mb.intrabc_hash_info.hash_value_buffer[0][0])));
Ravi Chaudhary783d6a32018-08-28 18:21:02 +05301283
chiyotsai82f36c92020-04-09 16:18:02 -07001284 cpi->td.mb.intrabc_hash_info.g_crc_initialized = 0;
Ravi Chaudhary783d6a32018-08-28 18:21:02 +05301285
Remya0cce44c2019-08-16 11:57:24 +05301286 CHECK_MEM_ERROR(cm, cpi->td.mb.mbmi_ext,
1287 aom_calloc(sb_mi_size, sizeof(*cpi->td.mb.mbmi_ext)));
1288
David Turner04b70d82019-01-24 15:39:19 +00001289 av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
1290 av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001291
sdengc23c7f12019-06-11 16:56:50 -07001292 {
1293 const int bsize = BLOCK_16X16;
1294 const int w = mi_size_wide[bsize];
1295 const int h = mi_size_high[bsize];
Urvang Joshi9dc909d2020-03-23 16:07:02 -07001296 const int num_cols = (mi_params->mi_cols + w - 1) / w;
1297 const int num_rows = (mi_params->mi_rows + h - 1) / h;
sdengf46a1062019-08-04 18:43:50 -07001298 CHECK_MEM_ERROR(cm, cpi->tpl_rdmult_scaling_factors,
1299 aom_calloc(num_rows * num_cols,
1300 sizeof(*cpi->tpl_rdmult_scaling_factors)));
1301 CHECK_MEM_ERROR(cm, cpi->tpl_sb_rdmult_scaling_factors,
1302 aom_calloc(num_rows * num_cols,
1303 sizeof(*cpi->tpl_sb_rdmult_scaling_factors)));
1304 }
1305
1306 {
1307 const int bsize = BLOCK_16X16;
1308 const int w = mi_size_wide[bsize];
1309 const int h = mi_size_high[bsize];
Urvang Joshi9dc909d2020-03-23 16:07:02 -07001310 const int num_cols = (mi_params->mi_cols + w - 1) / w;
1311 const int num_rows = (mi_params->mi_rows + h - 1) / h;
sdengc23c7f12019-06-11 16:56:50 -07001312 CHECK_MEM_ERROR(cm, cpi->ssim_rdmult_scaling_factors,
1313 aom_calloc(num_rows * num_cols,
1314 sizeof(*cpi->ssim_rdmult_scaling_factors)));
1315 }
1316
sdeng01959162019-12-20 10:46:24 -08001317#if CONFIG_TUNE_VMAF
1318 {
1319 const int bsize = BLOCK_64X64;
1320 const int w = mi_size_wide[bsize];
1321 const int h = mi_size_high[bsize];
Urvang Joshi9dc909d2020-03-23 16:07:02 -07001322 const int num_cols = (mi_params->mi_cols + w - 1) / w;
1323 const int num_rows = (mi_params->mi_rows + h - 1) / h;
Visheshf18766f2020-04-17 10:22:48 +05301324 CHECK_MEM_ERROR(cm, cpi->vmaf_info.rdmult_scaling_factors,
sdeng01959162019-12-20 10:46:24 -08001325 aom_calloc(num_rows * num_cols,
Visheshf18766f2020-04-17 10:22:48 +05301326 sizeof(*cpi->vmaf_info.rdmult_scaling_factors)));
1327 cpi->vmaf_info.last_frame_unsharp_amount = 0.0;
sdeng01959162019-12-20 10:46:24 -08001328 }
1329#endif
1330
Mufaddal Chakerae11600c2020-03-26 12:20:12 +05301331 if (!is_stat_generation_stage(cpi)) {
Vishesh39d03622020-03-31 15:18:16 +05301332 setup_tpl_buffers(cm, &cpi->tpl_data);
Jingning Hanf83d6812020-02-27 13:08:19 -08001333 }
Yue Chen7cae98f2018-08-24 10:43:16 -07001334
chiyotsai9c484b32019-03-07 16:01:50 -08001335#if CONFIG_COLLECT_PARTITION_STATS == 2
chiyotsai92ed0dd2019-01-25 14:50:14 -08001336 av1_zero(cpi->partition_stats);
1337#endif
1338
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001339#define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX4DF, JSDAF, JSVAF) \
1340 cpi->fn_ptr[BT].sdf = SDF; \
1341 cpi->fn_ptr[BT].sdaf = SDAF; \
1342 cpi->fn_ptr[BT].vf = VF; \
1343 cpi->fn_ptr[BT].svf = SVF; \
1344 cpi->fn_ptr[BT].svaf = SVAF; \
1345 cpi->fn_ptr[BT].sdx4df = SDX4DF; \
1346 cpi->fn_ptr[BT].jsdaf = JSDAF; \
Cheng Chenf78632e2017-10-20 15:30:51 -07001347 cpi->fn_ptr[BT].jsvaf = JSVAF;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348
Cheng Chenf78632e2017-10-20 15:30:51 -07001349 BFP(BLOCK_4X16, aom_sad4x16, aom_sad4x16_avg, aom_variance4x16,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001350 aom_sub_pixel_variance4x16, aom_sub_pixel_avg_variance4x16,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001351 aom_sad4x16x4d, aom_dist_wtd_sad4x16_avg,
1352 aom_dist_wtd_sub_pixel_avg_variance4x16)
Cheng Chenf78632e2017-10-20 15:30:51 -07001353
1354 BFP(BLOCK_16X4, aom_sad16x4, aom_sad16x4_avg, aom_variance16x4,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001355 aom_sub_pixel_variance16x4, aom_sub_pixel_avg_variance16x4,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001356 aom_sad16x4x4d, aom_dist_wtd_sad16x4_avg,
1357 aom_dist_wtd_sub_pixel_avg_variance16x4)
Cheng Chenf78632e2017-10-20 15:30:51 -07001358
1359 BFP(BLOCK_8X32, aom_sad8x32, aom_sad8x32_avg, aom_variance8x32,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001360 aom_sub_pixel_variance8x32, aom_sub_pixel_avg_variance8x32,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001361 aom_sad8x32x4d, aom_dist_wtd_sad8x32_avg,
1362 aom_dist_wtd_sub_pixel_avg_variance8x32)
Cheng Chenf78632e2017-10-20 15:30:51 -07001363
1364 BFP(BLOCK_32X8, aom_sad32x8, aom_sad32x8_avg, aom_variance32x8,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001365 aom_sub_pixel_variance32x8, aom_sub_pixel_avg_variance32x8,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001366 aom_sad32x8x4d, aom_dist_wtd_sad32x8_avg,
1367 aom_dist_wtd_sub_pixel_avg_variance32x8)
Cheng Chenf78632e2017-10-20 15:30:51 -07001368
1369 BFP(BLOCK_16X64, aom_sad16x64, aom_sad16x64_avg, aom_variance16x64,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001370 aom_sub_pixel_variance16x64, aom_sub_pixel_avg_variance16x64,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001371 aom_sad16x64x4d, aom_dist_wtd_sad16x64_avg,
1372 aom_dist_wtd_sub_pixel_avg_variance16x64)
Cheng Chenf78632e2017-10-20 15:30:51 -07001373
1374 BFP(BLOCK_64X16, aom_sad64x16, aom_sad64x16_avg, aom_variance64x16,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001375 aom_sub_pixel_variance64x16, aom_sub_pixel_avg_variance64x16,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001376 aom_sad64x16x4d, aom_dist_wtd_sad64x16_avg,
1377 aom_dist_wtd_sub_pixel_avg_variance64x16)
Cheng Chenf78632e2017-10-20 15:30:51 -07001378
Cheng Chenf78632e2017-10-20 15:30:51 -07001379 BFP(BLOCK_128X128, aom_sad128x128, aom_sad128x128_avg, aom_variance128x128,
1380 aom_sub_pixel_variance128x128, aom_sub_pixel_avg_variance128x128,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001381 aom_sad128x128x4d, aom_dist_wtd_sad128x128_avg,
1382 aom_dist_wtd_sub_pixel_avg_variance128x128)
Cheng Chenf78632e2017-10-20 15:30:51 -07001383
1384 BFP(BLOCK_128X64, aom_sad128x64, aom_sad128x64_avg, aom_variance128x64,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001385 aom_sub_pixel_variance128x64, aom_sub_pixel_avg_variance128x64,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001386 aom_sad128x64x4d, aom_dist_wtd_sad128x64_avg,
1387 aom_dist_wtd_sub_pixel_avg_variance128x64)
Cheng Chenf78632e2017-10-20 15:30:51 -07001388
1389 BFP(BLOCK_64X128, aom_sad64x128, aom_sad64x128_avg, aom_variance64x128,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001390 aom_sub_pixel_variance64x128, aom_sub_pixel_avg_variance64x128,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001391 aom_sad64x128x4d, aom_dist_wtd_sad64x128_avg,
1392 aom_dist_wtd_sub_pixel_avg_variance64x128)
Cheng Chenf78632e2017-10-20 15:30:51 -07001393
1394 BFP(BLOCK_32X16, aom_sad32x16, aom_sad32x16_avg, aom_variance32x16,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001395 aom_sub_pixel_variance32x16, aom_sub_pixel_avg_variance32x16,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001396 aom_sad32x16x4d, aom_dist_wtd_sad32x16_avg,
1397 aom_dist_wtd_sub_pixel_avg_variance32x16)
Cheng Chenf78632e2017-10-20 15:30:51 -07001398
1399 BFP(BLOCK_16X32, aom_sad16x32, aom_sad16x32_avg, aom_variance16x32,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001400 aom_sub_pixel_variance16x32, aom_sub_pixel_avg_variance16x32,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001401 aom_sad16x32x4d, aom_dist_wtd_sad16x32_avg,
1402 aom_dist_wtd_sub_pixel_avg_variance16x32)
Cheng Chenf78632e2017-10-20 15:30:51 -07001403
1404 BFP(BLOCK_64X32, aom_sad64x32, aom_sad64x32_avg, aom_variance64x32,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001405 aom_sub_pixel_variance64x32, aom_sub_pixel_avg_variance64x32,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001406 aom_sad64x32x4d, aom_dist_wtd_sad64x32_avg,
1407 aom_dist_wtd_sub_pixel_avg_variance64x32)
Cheng Chenf78632e2017-10-20 15:30:51 -07001408
1409 BFP(BLOCK_32X64, aom_sad32x64, aom_sad32x64_avg, aom_variance32x64,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001410 aom_sub_pixel_variance32x64, aom_sub_pixel_avg_variance32x64,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001411 aom_sad32x64x4d, aom_dist_wtd_sad32x64_avg,
1412 aom_dist_wtd_sub_pixel_avg_variance32x64)
Cheng Chenf78632e2017-10-20 15:30:51 -07001413
1414 BFP(BLOCK_32X32, aom_sad32x32, aom_sad32x32_avg, aom_variance32x32,
1415 aom_sub_pixel_variance32x32, aom_sub_pixel_avg_variance32x32,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001416 aom_sad32x32x4d, aom_dist_wtd_sad32x32_avg,
1417 aom_dist_wtd_sub_pixel_avg_variance32x32)
Cheng Chenf78632e2017-10-20 15:30:51 -07001418
1419 BFP(BLOCK_64X64, aom_sad64x64, aom_sad64x64_avg, aom_variance64x64,
1420 aom_sub_pixel_variance64x64, aom_sub_pixel_avg_variance64x64,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001421 aom_sad64x64x4d, aom_dist_wtd_sad64x64_avg,
1422 aom_dist_wtd_sub_pixel_avg_variance64x64)
Cheng Chenf78632e2017-10-20 15:30:51 -07001423
1424 BFP(BLOCK_16X16, aom_sad16x16, aom_sad16x16_avg, aom_variance16x16,
1425 aom_sub_pixel_variance16x16, aom_sub_pixel_avg_variance16x16,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001426 aom_sad16x16x4d, aom_dist_wtd_sad16x16_avg,
1427 aom_dist_wtd_sub_pixel_avg_variance16x16)
Cheng Chenf78632e2017-10-20 15:30:51 -07001428
1429 BFP(BLOCK_16X8, aom_sad16x8, aom_sad16x8_avg, aom_variance16x8,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001430 aom_sub_pixel_variance16x8, aom_sub_pixel_avg_variance16x8,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001431 aom_sad16x8x4d, aom_dist_wtd_sad16x8_avg,
1432 aom_dist_wtd_sub_pixel_avg_variance16x8)
Cheng Chenf78632e2017-10-20 15:30:51 -07001433
1434 BFP(BLOCK_8X16, aom_sad8x16, aom_sad8x16_avg, aom_variance8x16,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001435 aom_sub_pixel_variance8x16, aom_sub_pixel_avg_variance8x16,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001436 aom_sad8x16x4d, aom_dist_wtd_sad8x16_avg,
1437 aom_dist_wtd_sub_pixel_avg_variance8x16)
Cheng Chenf78632e2017-10-20 15:30:51 -07001438
1439 BFP(BLOCK_8X8, aom_sad8x8, aom_sad8x8_avg, aom_variance8x8,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001440 aom_sub_pixel_variance8x8, aom_sub_pixel_avg_variance8x8, aom_sad8x8x4d,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001441 aom_dist_wtd_sad8x8_avg, aom_dist_wtd_sub_pixel_avg_variance8x8)
Cheng Chenf78632e2017-10-20 15:30:51 -07001442
1443 BFP(BLOCK_8X4, aom_sad8x4, aom_sad8x4_avg, aom_variance8x4,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001444 aom_sub_pixel_variance8x4, aom_sub_pixel_avg_variance8x4, aom_sad8x4x4d,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001445 aom_dist_wtd_sad8x4_avg, aom_dist_wtd_sub_pixel_avg_variance8x4)
Cheng Chenf78632e2017-10-20 15:30:51 -07001446
1447 BFP(BLOCK_4X8, aom_sad4x8, aom_sad4x8_avg, aom_variance4x8,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001448 aom_sub_pixel_variance4x8, aom_sub_pixel_avg_variance4x8, aom_sad4x8x4d,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001449 aom_dist_wtd_sad4x8_avg, aom_dist_wtd_sub_pixel_avg_variance4x8)
Cheng Chenf78632e2017-10-20 15:30:51 -07001450
1451 BFP(BLOCK_4X4, aom_sad4x4, aom_sad4x4_avg, aom_variance4x4,
Kyle Siefringef6e2df2018-04-10 14:51:35 -04001452 aom_sub_pixel_variance4x4, aom_sub_pixel_avg_variance4x4, aom_sad4x4x4d,
Debargha Mukherjee0c96c112018-12-20 16:04:18 -08001453 aom_dist_wtd_sad4x4_avg, aom_dist_wtd_sub_pixel_avg_variance4x4)
Cheng Chenf78632e2017-10-20 15:30:51 -07001454
Yaowu Xuc27fc142016-08-22 16:08:15 -07001455#define OBFP(BT, OSDF, OVF, OSVF) \
1456 cpi->fn_ptr[BT].osdf = OSDF; \
1457 cpi->fn_ptr[BT].ovf = OVF; \
1458 cpi->fn_ptr[BT].osvf = OSVF;
1459
Yaowu Xuf883b422016-08-30 14:01:10 -07001460 OBFP(BLOCK_128X128, aom_obmc_sad128x128, aom_obmc_variance128x128,
1461 aom_obmc_sub_pixel_variance128x128)
1462 OBFP(BLOCK_128X64, aom_obmc_sad128x64, aom_obmc_variance128x64,
1463 aom_obmc_sub_pixel_variance128x64)
1464 OBFP(BLOCK_64X128, aom_obmc_sad64x128, aom_obmc_variance64x128,
1465 aom_obmc_sub_pixel_variance64x128)
Yaowu Xuf883b422016-08-30 14:01:10 -07001466 OBFP(BLOCK_64X64, aom_obmc_sad64x64, aom_obmc_variance64x64,
1467 aom_obmc_sub_pixel_variance64x64)
1468 OBFP(BLOCK_64X32, aom_obmc_sad64x32, aom_obmc_variance64x32,
1469 aom_obmc_sub_pixel_variance64x32)
1470 OBFP(BLOCK_32X64, aom_obmc_sad32x64, aom_obmc_variance32x64,
1471 aom_obmc_sub_pixel_variance32x64)
1472 OBFP(BLOCK_32X32, aom_obmc_sad32x32, aom_obmc_variance32x32,
1473 aom_obmc_sub_pixel_variance32x32)
1474 OBFP(BLOCK_32X16, aom_obmc_sad32x16, aom_obmc_variance32x16,
1475 aom_obmc_sub_pixel_variance32x16)
1476 OBFP(BLOCK_16X32, aom_obmc_sad16x32, aom_obmc_variance16x32,
1477 aom_obmc_sub_pixel_variance16x32)
1478 OBFP(BLOCK_16X16, aom_obmc_sad16x16, aom_obmc_variance16x16,
1479 aom_obmc_sub_pixel_variance16x16)
1480 OBFP(BLOCK_16X8, aom_obmc_sad16x8, aom_obmc_variance16x8,
1481 aom_obmc_sub_pixel_variance16x8)
1482 OBFP(BLOCK_8X16, aom_obmc_sad8x16, aom_obmc_variance8x16,
1483 aom_obmc_sub_pixel_variance8x16)
1484 OBFP(BLOCK_8X8, aom_obmc_sad8x8, aom_obmc_variance8x8,
1485 aom_obmc_sub_pixel_variance8x8)
1486 OBFP(BLOCK_4X8, aom_obmc_sad4x8, aom_obmc_variance4x8,
1487 aom_obmc_sub_pixel_variance4x8)
1488 OBFP(BLOCK_8X4, aom_obmc_sad8x4, aom_obmc_variance8x4,
1489 aom_obmc_sub_pixel_variance8x4)
1490 OBFP(BLOCK_4X4, aom_obmc_sad4x4, aom_obmc_variance4x4,
1491 aom_obmc_sub_pixel_variance4x4)
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001492 OBFP(BLOCK_4X16, aom_obmc_sad4x16, aom_obmc_variance4x16,
1493 aom_obmc_sub_pixel_variance4x16)
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001494 OBFP(BLOCK_16X4, aom_obmc_sad16x4, aom_obmc_variance16x4,
1495 aom_obmc_sub_pixel_variance16x4)
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001496 OBFP(BLOCK_8X32, aom_obmc_sad8x32, aom_obmc_variance8x32,
1497 aom_obmc_sub_pixel_variance8x32)
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001498 OBFP(BLOCK_32X8, aom_obmc_sad32x8, aom_obmc_variance32x8,
1499 aom_obmc_sub_pixel_variance32x8)
Rupert Swarbrick72678572017-08-02 12:05:26 +01001500 OBFP(BLOCK_16X64, aom_obmc_sad16x64, aom_obmc_variance16x64,
1501 aom_obmc_sub_pixel_variance16x64)
Rupert Swarbrick72678572017-08-02 12:05:26 +01001502 OBFP(BLOCK_64X16, aom_obmc_sad64x16, aom_obmc_variance64x16,
1503 aom_obmc_sub_pixel_variance64x16)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001504
David Barkerf19f35f2017-05-22 16:33:22 +01001505#define MBFP(BT, MCSDF, MCSVF) \
1506 cpi->fn_ptr[BT].msdf = MCSDF; \
1507 cpi->fn_ptr[BT].msvf = MCSVF;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001508
David Barkerf19f35f2017-05-22 16:33:22 +01001509 MBFP(BLOCK_128X128, aom_masked_sad128x128,
1510 aom_masked_sub_pixel_variance128x128)
1511 MBFP(BLOCK_128X64, aom_masked_sad128x64, aom_masked_sub_pixel_variance128x64)
1512 MBFP(BLOCK_64X128, aom_masked_sad64x128, aom_masked_sub_pixel_variance64x128)
David Barkerf19f35f2017-05-22 16:33:22 +01001513 MBFP(BLOCK_64X64, aom_masked_sad64x64, aom_masked_sub_pixel_variance64x64)
1514 MBFP(BLOCK_64X32, aom_masked_sad64x32, aom_masked_sub_pixel_variance64x32)
1515 MBFP(BLOCK_32X64, aom_masked_sad32x64, aom_masked_sub_pixel_variance32x64)
1516 MBFP(BLOCK_32X32, aom_masked_sad32x32, aom_masked_sub_pixel_variance32x32)
1517 MBFP(BLOCK_32X16, aom_masked_sad32x16, aom_masked_sub_pixel_variance32x16)
1518 MBFP(BLOCK_16X32, aom_masked_sad16x32, aom_masked_sub_pixel_variance16x32)
1519 MBFP(BLOCK_16X16, aom_masked_sad16x16, aom_masked_sub_pixel_variance16x16)
1520 MBFP(BLOCK_16X8, aom_masked_sad16x8, aom_masked_sub_pixel_variance16x8)
1521 MBFP(BLOCK_8X16, aom_masked_sad8x16, aom_masked_sub_pixel_variance8x16)
1522 MBFP(BLOCK_8X8, aom_masked_sad8x8, aom_masked_sub_pixel_variance8x8)
1523 MBFP(BLOCK_4X8, aom_masked_sad4x8, aom_masked_sub_pixel_variance4x8)
1524 MBFP(BLOCK_8X4, aom_masked_sad8x4, aom_masked_sub_pixel_variance8x4)
1525 MBFP(BLOCK_4X4, aom_masked_sad4x4, aom_masked_sub_pixel_variance4x4)
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001526
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001527 MBFP(BLOCK_4X16, aom_masked_sad4x16, aom_masked_sub_pixel_variance4x16)
1528
1529 MBFP(BLOCK_16X4, aom_masked_sad16x4, aom_masked_sub_pixel_variance16x4)
1530
1531 MBFP(BLOCK_8X32, aom_masked_sad8x32, aom_masked_sub_pixel_variance8x32)
1532
1533 MBFP(BLOCK_32X8, aom_masked_sad32x8, aom_masked_sub_pixel_variance32x8)
Rupert Swarbrick72678572017-08-02 12:05:26 +01001534
1535 MBFP(BLOCK_16X64, aom_masked_sad16x64, aom_masked_sub_pixel_variance16x64)
1536
1537 MBFP(BLOCK_64X16, aom_masked_sad64x16, aom_masked_sub_pixel_variance64x16)
Rupert Swarbrick2fa6e1c2017-09-11 12:38:10 +01001538
Jerome Jiangfa1d1732019-08-06 10:31:20 -07001539#if CONFIG_AV1_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001540 highbd_set_var_fns(cpi);
Jerome Jiangfa1d1732019-08-06 10:31:20 -07001541#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001542
Yaowu Xuf883b422016-08-30 14:01:10 -07001543 /* av1_init_quantizer() is first called here. Add check in
1544 * av1_frame_init_quantizer() so that av1_init_quantizer is only
Yaowu Xuc27fc142016-08-22 16:08:15 -07001545 * called later when needed. This will avoid unnecessary calls of
Yaowu Xuf883b422016-08-30 14:01:10 -07001546 * av1_init_quantizer() for every frame.
Yaowu Xuc27fc142016-08-22 16:08:15 -07001547 */
Deepa K Gc0d27832020-04-07 16:52:27 +05301548 av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
1549 cm->seq_params.bit_depth);
Urvang Joshi17814622020-03-27 17:26:17 -07001550 av1_qm_init(&cm->quant_params, av1_num_planes(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001551
Yaowu Xuf883b422016-08-30 14:01:10 -07001552 av1_loop_filter_init(cm);
Urvang Joshide71d142017-10-05 12:12:15 -07001553 cm->superres_scale_denominator = SCALE_NUMERATOR;
Vishesh2b8e4792020-06-12 12:11:19 +05301554 cm->superres_upscaled_width = oxcf->frm_dim_cfg.width;
1555 cm->superres_upscaled_height = oxcf->frm_dim_cfg.height;
Yaowu Xuf883b422016-08-30 14:01:10 -07001556 av1_loop_restoration_precal();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001557
1558 cm->error.setjmp = 0;
1559
1560 return cpi;
1561}
1562
Urvang Joshiee2c8112018-05-04 14:53:15 -07001563#if CONFIG_INTERNAL_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07001564#define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))
1565
1566#define SNPRINT2(H, T, V) \
1567 snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
Urvang Joshiee2c8112018-05-04 14:53:15 -07001568#endif // CONFIG_INTERNAL_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07001569
Sachin Kumar Garg700af532020-05-15 10:47:41 +05301570// This function will change the state and free the mutex of corresponding
1571// workers and terminate the object. The object can not be re-used unless a call
1572// to reset() is made.
1573static AOM_INLINE void terminate_worker_data(AV1_COMP *cpi) {
1574 MultiThreadInfo *const mt_info = &cpi->mt_info;
1575 for (int t = mt_info->num_workers - 1; t >= 0; --t) {
1576 AVxWorker *const worker = &mt_info->workers[t];
1577 aom_get_worker_interface()->end(worker);
1578 }
1579}
1580
1581// Deallocate allocated thread_data.
1582static AOM_INLINE void free_thread_data(AV1_COMP *cpi) {
1583 MultiThreadInfo *const mt_info = &cpi->mt_info;
1584 AV1_COMMON *cm = &cpi->common;
1585 for (int t = 0; t < mt_info->num_workers; ++t) {
1586 EncWorkerData *const thread_data = &mt_info->tile_thr_data[t];
1587 aom_free(thread_data->td->tctx);
1588 if (t == 0) continue;
1589 aom_free(thread_data->td->palette_buffer);
1590 aom_free(thread_data->td->tmp_conv_dst);
Satish Kumar Sumand3caa0d2020-06-16 14:02:50 +05301591 release_compound_type_rd_buffers(&thread_data->td->comp_rd_buffer);
Sachin Kumar Garg700af532020-05-15 10:47:41 +05301592 for (int j = 0; j < 2; ++j) {
1593 aom_free(thread_data->td->tmp_pred_bufs[j]);
1594 }
Satish Kumar Sumand3caa0d2020-06-16 14:02:50 +05301595 release_obmc_buffers(&thread_data->td->obmc_buffer);
Sachin Kumar Garg700af532020-05-15 10:47:41 +05301596 aom_free(thread_data->td->vt64x64);
1597
1598 aom_free(thread_data->td->inter_modes_info);
1599 for (int x = 0; x < 2; x++) {
1600 for (int y = 0; y < 2; y++) {
1601 aom_free(thread_data->td->hash_value_buffer[x][y]);
1602 thread_data->td->hash_value_buffer[x][y] = NULL;
1603 }
1604 }
1605 aom_free(thread_data->td->counts);
1606 aom_free(thread_data->td->mbmi_ext);
1607 av1_free_pmc(thread_data->td->firstpass_ctx, av1_num_planes(cm));
1608 thread_data->td->firstpass_ctx = NULL;
1609 av1_free_shared_coeff_buffer(&thread_data->td->shared_coeff_buf);
1610 av1_free_sms_tree(thread_data->td);
1611 aom_free(thread_data->td);
1612 }
1613}
1614
Yaowu Xuf883b422016-08-30 14:01:10 -07001615void av1_remove_compressor(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001616 if (!cpi) return;
1617
Yunqing Wang82f140a2020-06-03 18:40:50 -07001618 AV1_COMMON *cm = &cpi->common;
David Turnerd2a592e2018-11-16 14:59:31 +00001619 if (cm->current_frame.frame_number > 0) {
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08001620#if CONFIG_ENTROPY_STATS
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301621 if (!is_stat_generation_stage(cpi)) {
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08001622 fprintf(stderr, "Writing counts.stt\n");
1623 FILE *f = fopen("counts.stt", "wb");
1624 fwrite(&aggregate_fc, sizeof(aggregate_fc), 1, f);
1625 fclose(f);
1626 }
1627#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07001628#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07001629 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001630
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301631 if (!is_stat_generation_stage(cpi)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001632 char headings[512] = { 0 };
1633 char results[512] = { 0 };
1634 FILE *f = fopen("opsnr.stt", "a");
1635 double time_encoded =
Deepa K Gfb89ce02020-04-06 13:34:42 +05301636 (cpi->time_stamps.prev_end_seen - cpi->time_stamps.first_ever) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07001637 10000000.000;
1638 double total_encode_time =
1639 (cpi->time_receive_data + cpi->time_compress_data) / 1000.000;
1640 const double dr =
1641 (double)cpi->bytes * (double)8 / (double)1000 / time_encoded;
1642 const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1);
1643 const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000;
1644 const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
1645
1646 if (cpi->b_calculate_psnr) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001647 const double total_psnr = aom_sse_to_psnr(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001648 (double)cpi->total_samples, peak, (double)cpi->total_sq_error);
1649 const double total_ssim =
1650 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0);
1651 snprintf(headings, sizeof(headings),
Jingning Han87651b22017-11-28 20:02:26 -08001652 "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
Yaowu Xuf883b422016-08-30 14:01:10 -07001653 "AOMSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
Jingning Hanbe1ae3f2017-11-27 10:27:56 -08001654 "WstPsnr\tWstSsim\tWstFast\tWstHVS\t"
Yue Chenf0652ed2019-08-13 16:09:25 -07001655 "AVPsrnY\tAPsnrCb\tAPsnrCr");
Yaowu Xuc27fc142016-08-22 16:08:15 -07001656 snprintf(results, sizeof(results),
1657 "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
1658 "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
Jingning Hanbe1ae3f2017-11-27 10:27:56 -08001659 "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
Yue Chenf0652ed2019-08-13 16:09:25 -07001660 "%7.3f\t%7.3f\t%7.3f",
Wan-Teh Changc25c92a2018-04-23 15:04:14 -07001661 dr, cpi->psnr.stat[STAT_ALL] / cpi->count, total_psnr,
1662 cpi->psnr.stat[STAT_ALL] / cpi->count, total_psnr, total_ssim,
1663 total_ssim, cpi->fastssim.stat[STAT_ALL] / cpi->count,
1664 cpi->psnrhvs.stat[STAT_ALL] / cpi->count, cpi->psnr.worst,
Jingning Hanbe1ae3f2017-11-27 10:27:56 -08001665 cpi->worst_ssim, cpi->fastssim.worst, cpi->psnrhvs.worst,
Wan-Teh Changc25c92a2018-04-23 15:04:14 -07001666 cpi->psnr.stat[STAT_Y] / cpi->count,
1667 cpi->psnr.stat[STAT_U] / cpi->count,
Yue Chenf0652ed2019-08-13 16:09:25 -07001668 cpi->psnr.stat[STAT_V] / cpi->count);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001669
1670 if (cpi->b_calculate_blockiness) {
1671 SNPRINT(headings, "\t Block\tWstBlck");
1672 SNPRINT2(results, "\t%7.3f", cpi->total_blockiness / cpi->count);
1673 SNPRINT2(results, "\t%7.3f", cpi->worst_blockiness);
1674 }
1675
1676 if (cpi->b_calculate_consistency) {
1677 double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07001678 aom_sse_to_psnr((double)cpi->total_samples, peak,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001679 (double)cpi->total_inconsistency);
1680
1681 SNPRINT(headings, "\tConsist\tWstCons");
1682 SNPRINT2(results, "\t%7.3f", consistency);
1683 SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
1684 }
Yue Chenf0652ed2019-08-13 16:09:25 -07001685
1686 SNPRINT(headings, "\t Time\tRcErr\tAbsErr");
1687 SNPRINT2(results, "\t%8.0f", total_encode_time);
1688 SNPRINT2(results, "\t%7.2f", rate_err);
1689 SNPRINT2(results, "\t%7.2f", fabs(rate_err));
1690
1691 fprintf(f, "%s\tAPsnr611\n", headings);
1692 fprintf(f, "%s\t%7.3f\n", results,
1693 (6 * cpi->psnr.stat[STAT_Y] + cpi->psnr.stat[STAT_U] +
1694 cpi->psnr.stat[STAT_V]) /
1695 (cpi->count * 8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001696 }
1697
1698 fclose(f);
1699 }
Urvang Joshiee2c8112018-05-04 14:53:15 -07001700#endif // CONFIG_INTERNAL_STATS
Debargha Mukherjee0857e662019-01-04 16:22:09 -08001701#if CONFIG_SPEED_STATS
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301702 if (!is_stat_generation_stage(cpi)) {
Debargha Mukherjee0857e662019-01-04 16:22:09 -08001703 fprintf(stdout, "tx_search_count = %d\n", cpi->tx_search_count);
1704 }
1705#endif // CONFIG_SPEED_STATS
chiyotsai92ed0dd2019-01-25 14:50:14 -08001706
chiyotsai9c484b32019-03-07 16:01:50 -08001707#if CONFIG_COLLECT_PARTITION_STATS == 2
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301708 if (!is_stat_generation_stage(cpi)) {
chiyotsai92ed0dd2019-01-25 14:50:14 -08001709 av1_print_partition_stats(&cpi->partition_stats);
1710 }
1711#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001712 }
1713
Yunqing Wang82f140a2020-06-03 18:40:50 -07001714 TplParams *const tpl_data = &cpi->tpl_data;
Jingning Hanf83d6812020-02-27 13:08:19 -08001715 for (int frame = 0; frame < MAX_LAG_BUFFERS; ++frame) {
Vishesh39d03622020-03-31 15:18:16 +05301716 aom_free(tpl_data->tpl_stats_pool[frame]);
1717 aom_free_frame_buffer(&tpl_data->tpl_rec_pool[frame]);
Yue Chen7cae98f2018-08-24 10:43:16 -07001718 }
1719
Mufaddal Chakera91579252020-05-18 17:41:46 +05301720 if (cpi->compressor_stage != LAP_STAGE) {
1721 terminate_worker_data(cpi);
1722 free_thread_data(cpi);
1723 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001724
Yunqing Wang82f140a2020-06-03 18:40:50 -07001725 MultiThreadInfo *const mt_info = &cpi->mt_info;
Ravi Chaudhary90a15f42018-10-11 18:56:35 +05301726#if CONFIG_MULTITHREAD
Yunqing Wang82f140a2020-06-03 18:40:50 -07001727 pthread_mutex_t *const enc_row_mt_mutex_ = mt_info->enc_row_mt.mutex_;
1728 pthread_mutex_t *const gm_mt_mutex_ = mt_info->gm_sync.mutex_;
Deepa K G74de2a02020-04-11 13:09:11 +05301729 if (enc_row_mt_mutex_ != NULL) {
1730 pthread_mutex_destroy(enc_row_mt_mutex_);
1731 aom_free(enc_row_mt_mutex_);
Ravi Chaudhary90a15f42018-10-11 18:56:35 +05301732 }
Remya1a090d52020-05-04 11:52:10 +05301733 if (gm_mt_mutex_ != NULL) {
1734 pthread_mutex_destroy(gm_mt_mutex_);
1735 aom_free(gm_mt_mutex_);
1736 }
Ravi Chaudhary90a15f42018-10-11 18:56:35 +05301737#endif
Ravi Chaudharyc5e74692018-10-08 16:05:38 +05301738 av1_row_mt_mem_dealloc(cpi);
Mufaddal Chakera91579252020-05-18 17:41:46 +05301739 if (cpi->compressor_stage != LAP_STAGE) {
1740 aom_free(mt_info->tile_thr_data);
1741 aom_free(mt_info->workers);
1742 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001743
Sachin Kumar Garg194c57b2020-05-06 08:50:13 +05301744#if !CONFIG_REALTIME_ONLY
1745 av1_tpl_dealloc(&tpl_data->tpl_mt_sync);
1746#endif
Deepa K G74de2a02020-04-11 13:09:11 +05301747 if (mt_info->num_workers > 1) {
1748 av1_loop_filter_dealloc(&mt_info->lf_row_sync);
1749 av1_loop_restoration_dealloc(&mt_info->lr_row_sync, mt_info->num_workers);
Remya1a090d52020-05-04 11:52:10 +05301750 av1_gm_dealloc(&mt_info->gm_sync);
Deepa K G964e72e2018-05-16 16:56:01 +05301751 }
1752
Yaowu Xuc27fc142016-08-22 16:08:15 -07001753 dealloc_compressor_data(cpi);
1754
Debargha Mukherjee5d157212017-01-10 14:44:47 -08001755#if CONFIG_INTERNAL_STATS
1756 aom_free(cpi->ssim_vars);
1757 cpi->ssim_vars = NULL;
1758#endif // CONFIG_INTERNAL_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07001759
Yaowu Xuf883b422016-08-30 14:01:10 -07001760 av1_remove_common(cm);
Yaowu Xu74e63352019-05-06 09:21:33 -07001761#if CONFIG_HTB_TRELLIS
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001762 if (cpi->sf.use_hash_based_trellis) hbt_destroy();
Yaowu Xu74e63352019-05-06 09:21:33 -07001763#endif // CONFIG_HTB_TRELLIS
Yaowu Xuf883b422016-08-30 14:01:10 -07001764 av1_free_ref_frame_buffers(cm->buffer_pool);
Mufaddal Chakera74c9cbe2020-01-17 16:44:59 +05301765
Yaowu Xuf883b422016-08-30 14:01:10 -07001766 aom_free(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001767
Yaowu Xuc27fc142016-08-22 16:08:15 -07001768#ifdef OUTPUT_YUV_REC
1769 fclose(yuv_rec_file);
1770#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001771}
1772
Yaowu Xuf883b422016-08-30 14:01:10 -07001773static void generate_psnr_packet(AV1_COMP *cpi) {
1774 struct aom_codec_cx_pkt pkt;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001775 int i;
1776 PSNR_STATS psnr;
Jerome Jiangfa1d1732019-08-06 10:31:20 -07001777#if CONFIG_AV1_HIGHBITDEPTH
Yaowu Xue75b58a2020-01-03 12:56:12 -08001778 const uint32_t in_bit_depth = cpi->oxcf.input_bit_depth;
1779 const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
1780 aom_calc_highbd_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr,
1781 bit_depth, in_bit_depth);
Jerome Jiangfa1d1732019-08-06 10:31:20 -07001782#else
1783 aom_calc_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr);
1784#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001785
1786 for (i = 0; i < 4; ++i) {
1787 pkt.data.psnr.samples[i] = psnr.samples[i];
1788 pkt.data.psnr.sse[i] = psnr.sse[i];
1789 pkt.data.psnr.psnr[i] = psnr.psnr[i];
1790 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001791 pkt.kind = AOM_CODEC_PSNR_PKT;
1792 aom_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001793}
1794
Vishesha195ca32020-04-07 18:46:20 +05301795int av1_use_as_reference(int *ext_ref_frame_flags, int ref_frame_flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001796 if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
1797
Vishesha195ca32020-04-07 18:46:20 +05301798 *ext_ref_frame_flags = ref_frame_flags;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001799 return 0;
1800}
1801
Thomas Daede497d1952017-08-08 17:33:06 -07001802int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) {
1803 AV1_COMMON *const cm = &cpi->common;
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00001804 const int num_planes = av1_num_planes(cm);
Thomas Daede497d1952017-08-08 17:33:06 -07001805 YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001806 if (cfg) {
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00001807 aom_yv12_copy_frame(cfg, sd, num_planes);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001808 return 0;
1809 } else {
1810 return -1;
1811 }
1812}
1813
Thomas Daede497d1952017-08-08 17:33:06 -07001814int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) {
1815 AV1_COMMON *const cm = &cpi->common;
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00001816 const int num_planes = av1_num_planes(cm);
Thomas Daede497d1952017-08-08 17:33:06 -07001817 YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07001818 if (cfg) {
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00001819 aom_yv12_copy_frame(sd, cfg, num_planes);
Yaowu Xuf883b422016-08-30 14:01:10 -07001820 return 0;
1821 } else {
1822 return -1;
1823 }
1824}
1825
Yaowu Xuc27fc142016-08-22 16:08:15 -07001826#ifdef OUTPUT_YUV_REC
Yaowu Xuf883b422016-08-30 14:01:10 -07001827void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001828 uint8_t *src = s->y_buffer;
1829 int h = cm->height;
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07001830 if (yuv_rec_file == NULL) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001831 if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
1832 uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
1833
1834 do {
1835 fwrite(src16, s->y_width, 2, yuv_rec_file);
1836 src16 += s->y_stride;
1837 } while (--h);
1838
1839 src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
1840 h = s->uv_height;
1841
1842 do {
1843 fwrite(src16, s->uv_width, 2, yuv_rec_file);
1844 src16 += s->uv_stride;
1845 } while (--h);
1846
1847 src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
1848 h = s->uv_height;
1849
1850 do {
1851 fwrite(src16, s->uv_width, 2, yuv_rec_file);
1852 src16 += s->uv_stride;
1853 } while (--h);
1854
1855 fflush(yuv_rec_file);
1856 return;
1857 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001858
1859 do {
1860 fwrite(src, s->y_width, 1, yuv_rec_file);
1861 src += s->y_stride;
1862 } while (--h);
1863
1864 src = s->u_buffer;
1865 h = s->uv_height;
1866
1867 do {
1868 fwrite(src, s->uv_width, 1, yuv_rec_file);
1869 src += s->uv_stride;
1870 } while (--h);
1871
1872 src = s->v_buffer;
1873 h = s->uv_height;
1874
1875 do {
1876 fwrite(src, s->uv_width, 1, yuv_rec_file);
1877 src += s->uv_stride;
1878 } while (--h);
1879
1880 fflush(yuv_rec_file);
1881}
1882#endif // OUTPUT_YUV_REC
1883
Marco Paniconic6cd72e2020-05-08 11:00:50 -07001884#if !CONFIG_REALTIME_ONLY
Debargha Mukherjee11f0e402017-03-29 07:42:40 -07001885#define GM_RECODE_LOOP_NUM4X4_FACTOR 192
Vishesh8ba8bfe2020-04-03 14:20:29 +05301886static int recode_loop_test_global_motion(
1887 WarpedMotionParams *const global_motion,
1888 const int *const global_motion_used, int *const gm_params_cost) {
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08001889 int i;
1890 int recode = 0;
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08001891 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
Vishesh8ba8bfe2020-04-03 14:20:29 +05301892 if (global_motion[i].wmtype != IDENTITY &&
1893 global_motion_used[i] * GM_RECODE_LOOP_NUM4X4_FACTOR <
1894 gm_params_cost[i]) {
1895 global_motion[i] = default_warp_params;
1896 assert(global_motion[i].wmtype == IDENTITY);
1897 gm_params_cost[i] = 0;
David Barker43479c62016-11-30 10:34:20 +00001898 recode = 1;
Urvang Joshi02aade82017-12-18 17:18:16 -08001899 // TODO(sarahparker): The earlier condition for recoding here was:
1900 // "recode |= (rdc->global_motion_used[i] > 0);". Can we bring something
1901 // similar to that back to speed up global motion?
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08001902 }
1903 }
1904 return recode;
1905}
Marco Paniconic6cd72e2020-05-08 11:00:50 -07001906#endif // !CONFIG_REALTIME_ONLY
Yaowu Xuc27fc142016-08-22 16:08:15 -07001907
Jerome Jiangdede2932020-06-23 16:49:41 -07001908static void scale_references(AV1_COMP *cpi, const InterpFilter filter,
1909 const int phase) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001910 AV1_COMMON *cm = &cpi->common;
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00001911 const int num_planes = av1_num_planes(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001912 MV_REFERENCE_FRAME ref_frame;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001913
1914 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001915 // Need to convert from AOM_REFFRAME to index into ref_mask (subtract 1).
Jingning Han667561a2019-07-22 15:48:01 -07001916 if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001917 BufferPool *const pool = cm->buffer_pool;
1918 const YV12_BUFFER_CONFIG *const ref =
David Turnera21966b2018-12-05 14:48:49 +00001919 get_ref_frame_yv12_buf(cm, ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001920
1921 if (ref == NULL) {
David Turnere7ebf902018-12-04 14:04:55 +00001922 cpi->scaled_ref_buf[ref_frame - 1] = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001923 continue;
1924 }
1925
Yaowu Xuc27fc142016-08-22 16:08:15 -07001926 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
Debargha Mukherjee13cccf22019-03-27 23:49:14 -07001927 // Replace the reference buffer with a copy having a thicker border,
1928 // if the reference buffer is higher resolution than the current
1929 // frame, and the border is thin.
1930 if ((ref->y_crop_width > cm->width ||
1931 ref->y_crop_height > cm->height) &&
1932 ref->border < AOM_BORDER_IN_PIXELS) {
1933 RefCntBuffer *ref_fb = get_ref_frame_buf(cm, ref_frame);
1934 if (aom_yv12_realloc_with_new_border(
Urvang Joshi6237b882020-03-26 15:02:26 -07001935 &ref_fb->buf, AOM_BORDER_IN_PIXELS,
1936 cm->features.byte_alignment, num_planes) != 0) {
Debargha Mukherjee13cccf22019-03-27 23:49:14 -07001937 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
1938 "Failed to allocate frame buffer");
1939 }
1940 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001941 int force_scaling = 0;
David Turnere7ebf902018-12-04 14:04:55 +00001942 RefCntBuffer *new_fb = cpi->scaled_ref_buf[ref_frame - 1];
1943 if (new_fb == NULL) {
1944 const int new_fb_idx = get_free_fb(cm);
1945 if (new_fb_idx == INVALID_IDX) {
Wan-Teh Chang4a8c0042018-10-05 09:41:52 -07001946 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
1947 "Unable to find free frame buffer");
David Turnere7ebf902018-12-04 14:04:55 +00001948 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001949 force_scaling = 1;
David Turnere7ebf902018-12-04 14:04:55 +00001950 new_fb = &pool->frame_bufs[new_fb_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001951 }
David Turnere7ebf902018-12-04 14:04:55 +00001952
1953 if (force_scaling || new_fb->buf.y_crop_width != cm->width ||
1954 new_fb->buf.y_crop_height != cm->height) {
Yaowu Xu671f2bd2016-09-30 15:07:57 -07001955 if (aom_realloc_frame_buffer(
David Turnere7ebf902018-12-04 14:04:55 +00001956 &new_fb->buf, cm->width, cm->height,
Urvang Joshi20cf30e2018-07-19 02:33:58 -07001957 cm->seq_params.subsampling_x, cm->seq_params.subsampling_y,
Debargha Mukherjeefa946af2019-03-26 16:58:55 -07001958 cm->seq_params.use_highbitdepth, AOM_BORDER_IN_PIXELS,
Urvang Joshi6237b882020-03-26 15:02:26 -07001959 cm->features.byte_alignment, NULL, NULL, NULL)) {
Wan-Teh Chang41d286f2018-10-03 11:43:03 -07001960 if (force_scaling) {
1961 // Release the reference acquired in the get_free_fb() call above.
David Turnere7ebf902018-12-04 14:04:55 +00001962 --new_fb->ref_count;
Wan-Teh Chang41d286f2018-10-03 11:43:03 -07001963 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001964 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001965 "Failed to allocate frame buffer");
Wan-Teh Chang41d286f2018-10-03 11:43:03 -07001966 }
Jerome Jiangdede2932020-06-23 16:49:41 -07001967#if CONFIG_AV1_HIGHBITDEPTH
1968 if ((cm->width << 1) == ref->y_crop_width &&
1969 (cm->height << 1) == ref->y_crop_height &&
1970 cm->seq_params.bit_depth == AOM_BITS_8)
1971 av1_resize_and_extend_frame(ref, &new_fb->buf, filter, phase,
1972 num_planes);
1973 else
1974 av1_resize_and_extend_frame_nonnormative(
1975 ref, &new_fb->buf, (int)cm->seq_params.bit_depth, num_planes);
1976#else
1977 if ((cm->width << 1) == ref->y_crop_width &&
1978 (cm->height << 1) == ref->y_crop_height)
1979 av1_resize_and_extend_frame(ref, &new_fb->buf, filter, phase,
1980 num_planes);
1981 else
1982 av1_resize_and_extend_frame_nonnormative(
1983 ref, &new_fb->buf, (int)cm->seq_params.bit_depth, num_planes);
1984#endif
David Turnere7ebf902018-12-04 14:04:55 +00001985 cpi->scaled_ref_buf[ref_frame - 1] = new_fb;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001986 alloc_frame_mvs(cm, new_fb);
1987 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001988 } else {
David Turnera21966b2018-12-05 14:48:49 +00001989 RefCntBuffer *buf = get_ref_frame_buf(cm, ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001990 buf->buf.y_crop_width = ref->y_crop_width;
1991 buf->buf.y_crop_height = ref->y_crop_height;
David Turnere7ebf902018-12-04 14:04:55 +00001992 cpi->scaled_ref_buf[ref_frame - 1] = buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001993 ++buf->ref_count;
1994 }
1995 } else {
Mufaddal Chakera3bcc72c2019-12-11 14:38:37 +05301996 if (!has_no_stats_stage(cpi)) cpi->scaled_ref_buf[ref_frame - 1] = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001997 }
1998 }
1999}
2000
Yaowu Xuf883b422016-08-30 14:01:10 -07002001static void release_scaled_references(AV1_COMP *cpi) {
Imdad Sardharwalladadaba62018-02-23 12:06:56 +00002002 // TODO(isbs): only refresh the necessary frames, rather than all of them
David Turnere7ebf902018-12-04 14:04:55 +00002003 for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
2004 RefCntBuffer *const buf = cpi->scaled_ref_buf[i];
2005 if (buf != NULL) {
Imdad Sardharwalladadaba62018-02-23 12:06:56 +00002006 --buf->ref_count;
David Turnere7ebf902018-12-04 14:04:55 +00002007 cpi->scaled_ref_buf[i] = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002008 }
2009 }
2010}
2011
Yaowu Xuf883b422016-08-30 14:01:10 -07002012static void set_mv_search_params(AV1_COMP *cpi) {
2013 const AV1_COMMON *const cm = &cpi->common;
Nithya V Sace29f32020-04-07 16:15:12 +05302014 MotionVectorSearchParams *const mv_search_params = &cpi->mv_search_params;
Yunqing Wang4b7bf402020-01-28 15:20:53 -08002015 const int max_mv_def = AOMMAX(cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002016
2017 // Default based on max resolution.
Nithya V Sace29f32020-04-07 16:15:12 +05302018 mv_search_params->mv_step_param = av1_init_search_range(max_mv_def);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002019
chiyotsai8cc054a2019-12-12 14:57:43 -08002020 if (cpi->sf.mv_sf.auto_mv_step_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002021 if (frame_is_intra_only(cm)) {
2022 // Initialize max_mv_magnitude for use in the first INTER frame
2023 // after a key/intra-only frame.
Nithya V Sace29f32020-04-07 16:15:12 +05302024 mv_search_params->max_mv_magnitude = max_mv_def;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002025 } else {
Yunqing Wang4b7bf402020-01-28 15:20:53 -08002026 // Use cpi->max_mv_magnitude == -1 to exclude first pass case.
Nithya V Sace29f32020-04-07 16:15:12 +05302027 if (cm->show_frame && mv_search_params->max_mv_magnitude != -1) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002028 // Allow mv_steps to correspond to twice the max mv magnitude found
2029 // in the previous frame, capped by the default max_mv_magnitude based
2030 // on resolution.
Nithya V Sace29f32020-04-07 16:15:12 +05302031 mv_search_params->mv_step_param = av1_init_search_range(
2032 AOMMIN(max_mv_def, 2 * mv_search_params->max_mv_magnitude));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002033 }
Nithya V Sace29f32020-04-07 16:15:12 +05302034 mv_search_params->max_mv_magnitude = -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002035 }
2036 }
2037}
2038
Yaowu Xubca61902020-04-08 08:41:47 -07002039void av1_set_screen_content_options(const AV1_COMP *cpi,
2040 FeatureFlags *features) {
Urvang Joshib6409e92020-03-23 11:23:27 -07002041 const AV1_COMMON *const cm = &cpi->common;
Hui Subdf0c992019-02-14 14:52:41 -08002042
2043 if (cm->seq_params.force_screen_content_tools != 2) {
Urvang Joshib6409e92020-03-23 11:23:27 -07002044 features->allow_screen_content_tools = features->allow_intrabc =
Hui Subdf0c992019-02-14 14:52:41 -08002045 cm->seq_params.force_screen_content_tools;
2046 return;
2047 }
2048
2049 if (cpi->oxcf.content == AOM_CONTENT_SCREEN) {
Urvang Joshib6409e92020-03-23 11:23:27 -07002050 features->allow_screen_content_tools = features->allow_intrabc = 1;
Hui Subdf0c992019-02-14 14:52:41 -08002051 return;
2052 }
2053
2054 // Estimate if the source frame is screen content, based on the portion of
2055 // blocks that have few luma colors.
Cheng Chen4f666ca2019-11-18 17:05:03 -08002056 const uint8_t *src = cpi->unfiltered_source->y_buffer;
Hui Subdf0c992019-02-14 14:52:41 -08002057 assert(src != NULL);
Cheng Chen4f666ca2019-11-18 17:05:03 -08002058 const int use_hbd = cpi->unfiltered_source->flags & YV12_FLAG_HIGHBITDEPTH;
2059 const int stride = cpi->unfiltered_source->y_stride;
2060 const int width = cpi->unfiltered_source->y_width;
2061 const int height = cpi->unfiltered_source->y_height;
Hui Subdf0c992019-02-14 14:52:41 -08002062 const int bd = cm->seq_params.bit_depth;
2063 const int blk_w = 16;
2064 const int blk_h = 16;
2065 // These threshold values are selected experimentally.
2066 const int color_thresh = 4;
2067 const unsigned int var_thresh = 0;
2068 // Counts of blocks with no more than color_thresh colors.
2069 int counts_1 = 0;
2070 // Counts of blocks with no more than color_thresh colors and variance larger
2071 // than var_thresh.
2072 int counts_2 = 0;
2073
2074 for (int r = 0; r + blk_h <= height; r += blk_h) {
2075 for (int c = 0; c + blk_w <= width; c += blk_w) {
2076 int count_buf[1 << 12]; // Maximum (1 << 12) color levels.
2077 const uint8_t *const this_src = src + r * stride + c;
2078 const int n_colors =
2079 use_hbd ? av1_count_colors_highbd(this_src, stride, blk_w, blk_h, bd,
2080 count_buf)
2081 : av1_count_colors(this_src, stride, blk_w, blk_h, count_buf);
2082 if (n_colors > 1 && n_colors <= color_thresh) {
2083 ++counts_1;
2084 struct buf_2d buf;
2085 buf.stride = stride;
2086 buf.buf = (uint8_t *)this_src;
2087 const unsigned int var =
2088 use_hbd
2089 ? av1_high_get_sby_perpixel_variance(cpi, &buf, BLOCK_16X16, bd)
2090 : av1_get_sby_perpixel_variance(cpi, &buf, BLOCK_16X16);
2091 if (var > var_thresh) ++counts_2;
2092 }
2093 }
2094 }
2095
2096 // The threshold values are selected experimentally.
Urvang Joshib6409e92020-03-23 11:23:27 -07002097 features->allow_screen_content_tools =
Hui Subdf0c992019-02-14 14:52:41 -08002098 counts_1 * blk_h * blk_w * 10 > width * height;
2099 // IntraBC would force loop filters off, so we use more strict rules that also
2100 // requires that the block has high variance.
Urvang Joshib6409e92020-03-23 11:23:27 -07002101 features->allow_intrabc = features->allow_screen_content_tools &&
2102 counts_2 * blk_h * blk_w * 12 > width * height;
Hui Subdf0c992019-02-14 14:52:41 -08002103}
2104
Yaowu Xuf883b422016-08-30 14:01:10 -07002105static void set_size_independent_vars(AV1_COMP *cpi) {
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002106 int i;
Urvang Joshib6409e92020-03-23 11:23:27 -07002107 AV1_COMMON *const cm = &cpi->common;
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002108 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
Debargha Mukherjeedf713102018-10-02 12:33:32 -07002109 cm->global_motion[i] = default_warp_params;
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002110 }
Vishesh8ba8bfe2020-04-03 14:20:29 +05302111 cpi->gm_info.search_done = 0;
Yunqing Wang9411e432019-03-14 15:53:23 -07002112
David Turner04b70d82019-01-24 15:39:19 +00002113 av1_set_speed_features_framesize_independent(cpi, cpi->speed);
Yaowu Xuf883b422016-08-30 14:01:10 -07002114 av1_set_rd_speed_thresholds(cpi);
Urvang Joshi6237b882020-03-26 15:02:26 -07002115 cm->features.interp_filter = SWITCHABLE;
2116 cm->features.switchable_motion_mode = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002117}
2118
Mufaddal Chakerac956d2d2020-02-12 15:42:23 +05302119#define MIN_BOOST_COMBINE_FACTOR 4.0
2120#define MAX_BOOST_COMBINE_FACTOR 12.0
Debargha Mukherjeeafd3cc22019-06-10 11:35:17 -07002121
Jerome Jiangd413f4a2019-09-23 14:53:03 -07002122#if !CONFIG_REALTIME_ONLY
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002123static void process_tpl_stats_frame(AV1_COMP *cpi) {
Sarah Parkere1b22012019-06-06 16:35:25 -07002124 const GF_GROUP *const gf_group = &cpi->gf_group;
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002125 AV1_COMMON *const cm = &cpi->common;
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002126
Sarah Parkere1b22012019-06-06 16:35:25 -07002127 assert(IMPLIES(gf_group->size > 0, gf_group->index < gf_group->size));
Jingning Han31a0ee92019-07-15 13:56:55 -07002128
2129 const int tpl_idx = gf_group->index;
Vishesh39d03622020-03-31 15:18:16 +05302130 TplParams *const tpl_data = &cpi->tpl_data;
2131 TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
Yue Chen4e585cc2019-06-03 14:47:16 -07002132 TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002133
Yue Chen4e585cc2019-06-03 14:47:16 -07002134 if (tpl_frame->is_valid) {
2135 int tpl_stride = tpl_frame->stride;
2136 int64_t intra_cost_base = 0;
2137 int64_t mc_dep_cost_base = 0;
2138 int64_t mc_saved_base = 0;
2139 int64_t mc_count_base = 0;
Vishesh39d03622020-03-31 15:18:16 +05302140 const int step = 1 << tpl_data->tpl_stats_block_mis_log2;
Debargha Mukherjeeedfa4fe2019-07-08 14:23:39 -07002141 const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
Yue Chenb4c93f02019-08-05 13:47:31 -07002142
Urvang Joshi9dc909d2020-03-23 16:07:02 -07002143 for (int row = 0; row < cm->mi_params.mi_rows; row += step) {
Yue Chenb4c93f02019-08-05 13:47:31 -07002144 for (int col = 0; col < mi_cols_sr; col += step) {
Vishesha9349502020-04-01 01:54:30 +05302145 TplDepStats *this_stats = &tpl_stats[av1_tpl_ptr_pos(
2146 row, col, tpl_stride, tpl_data->tpl_stats_block_mis_log2)];
Jingning Han40e870f2019-10-02 16:05:39 -07002147 int64_t mc_dep_delta =
2148 RDCOST(tpl_frame->base_rdmult, this_stats->mc_dep_rate,
2149 this_stats->mc_dep_dist);
2150 intra_cost_base += (this_stats->recrf_dist << RDDIV_BITS);
2151 mc_dep_cost_base +=
2152 (this_stats->recrf_dist << RDDIV_BITS) + mc_dep_delta;
Yue Chen4e585cc2019-06-03 14:47:16 -07002153 mc_count_base += this_stats->mc_count;
2154 mc_saved_base += this_stats->mc_saved;
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002155 }
Yue Chen4e585cc2019-06-03 14:47:16 -07002156 }
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002157
Yue Chen4e585cc2019-06-03 14:47:16 -07002158 if (mc_dep_cost_base == 0) {
2159 tpl_frame->is_valid = 0;
2160 } else {
2161 aom_clear_system_state();
2162 cpi->rd.r0 = (double)intra_cost_base / mc_dep_cost_base;
Jingning Han9102cce2020-06-23 11:40:35 -07002163 if (is_frame_tpl_eligible(gf_group)) {
Yue Chen4e585cc2019-06-03 14:47:16 -07002164 cpi->rd.arf_r0 = cpi->rd.r0;
Mufaddal Chakerac956d2d2020-02-12 15:42:23 +05302165 if (cpi->lap_enabled) {
2166 double min_boost_factor = sqrt(cpi->rc.baseline_gf_interval);
2167 const int gfu_boost = get_gfu_boost_from_r0_lap(
2168 min_boost_factor, MAX_GFUBOOST_FACTOR, cpi->rd.arf_r0,
2169 cpi->rc.num_stats_required_for_gfu_boost);
Mufaddal Chakera0ec9bb62020-02-25 14:23:10 +05302170 // printf("old boost %d new boost %d\n", cpi->rc.gfu_boost,
Mufaddal Chakerac956d2d2020-02-12 15:42:23 +05302171 // gfu_boost);
2172 cpi->rc.gfu_boost = combine_prior_with_tpl_boost(
Mufaddal Chakera0ec9bb62020-02-25 14:23:10 +05302173 min_boost_factor, MAX_BOOST_COMBINE_FACTOR, cpi->rc.gfu_boost,
Mufaddal Chakerac956d2d2020-02-12 15:42:23 +05302174 gfu_boost, cpi->rc.num_stats_used_for_gfu_boost);
2175 } else {
2176 const int gfu_boost = (int)(200.0 / cpi->rd.r0);
2177 cpi->rc.gfu_boost = combine_prior_with_tpl_boost(
2178 MIN_BOOST_COMBINE_FACTOR, MAX_BOOST_COMBINE_FACTOR,
2179 cpi->rc.gfu_boost, gfu_boost, cpi->rc.frames_to_key);
2180 }
Debargha Mukherjeeafd3cc22019-06-10 11:35:17 -07002181 } else if (frame_is_intra_only(cm)) {
Debargha Mukherjee0a121a92019-06-19 13:12:46 -07002182 // TODO(debargha): Turn off q adjustment for kf temporarily to
2183 // reduce impact on speed of encoding. Need to investigate how
2184 // to mitigate the issue.
Vishesh39e74092020-06-16 17:13:48 +05302185 if (cpi->oxcf.rc_cfg.mode == AOM_Q) {
Debargha Mukherjee0a121a92019-06-19 13:12:46 -07002186 const int kf_boost =
2187 get_kf_boost_from_r0(cpi->rd.r0, cpi->rc.frames_to_key);
Aasaipriya197771d2020-02-06 20:11:21 +05302188 if (cpi->lap_enabled) {
Aasaipriya197771d2020-02-06 20:11:21 +05302189 cpi->rc.kf_boost = combine_prior_with_tpl_boost(
Mufaddal Chakerac956d2d2020-02-12 15:42:23 +05302190 MIN_BOOST_COMBINE_FACTOR, MAX_BOOST_COMBINE_FACTOR,
Mufaddal Chakera0ec9bb62020-02-25 14:23:10 +05302191 cpi->rc.kf_boost, kf_boost,
Aasaipriya197771d2020-02-06 20:11:21 +05302192 cpi->rc.num_stats_used_for_kf_boost);
2193 } else {
2194 cpi->rc.kf_boost = combine_prior_with_tpl_boost(
Mufaddal Chakerac956d2d2020-02-12 15:42:23 +05302195 MIN_BOOST_COMBINE_FACTOR, MAX_BOOST_COMBINE_FACTOR,
Aasaipriya197771d2020-02-06 20:11:21 +05302196 cpi->rc.kf_boost, kf_boost, cpi->rc.frames_to_key);
2197 }
Debargha Mukherjee0a121a92019-06-19 13:12:46 -07002198 }
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002199 }
Urvang Joshi9dc909d2020-03-23 16:07:02 -07002200 cpi->rd.mc_count_base = (double)mc_count_base /
2201 (cm->mi_params.mi_rows * cm->mi_params.mi_cols);
2202 cpi->rd.mc_saved_base = (double)mc_saved_base /
2203 (cm->mi_params.mi_rows * cm->mi_params.mi_cols);
Yue Chen4e585cc2019-06-03 14:47:16 -07002204 aom_clear_system_state();
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002205 }
2206 }
2207}
Jerome Jiangd413f4a2019-09-23 14:53:03 -07002208#endif // !CONFIG_REALTIME_ONLY
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002209
Yaowu Xuf883b422016-08-30 14:01:10 -07002210static void set_size_dependent_vars(AV1_COMP *cpi, int *q, int *bottom_index,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002211 int *top_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002212 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002213
2214 // Setup variables that depend on the dimensions of the frame.
David Turner04b70d82019-01-24 15:39:19 +00002215 av1_set_speed_features_framesize_dependent(cpi, cpi->speed);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002216
Jerome Jiangd413f4a2019-09-23 14:53:03 -07002217#if !CONFIG_REALTIME_ONLY
Jingning Han9102cce2020-06-23 11:40:35 -07002218 GF_GROUP *gf_group = &cpi->gf_group;
2219 if (cpi->oxcf.enable_tpl_model && is_frame_tpl_eligible(gf_group)) {
Yue Chen4e585cc2019-06-03 14:47:16 -07002220 process_tpl_stats_frame(cpi);
sdengf46a1062019-08-04 18:43:50 -07002221 av1_tpl_rdmult_setup(cpi);
2222 }
Jerome Jiangd413f4a2019-09-23 14:53:03 -07002223#endif
Debargha Mukherjeed0c0b772019-05-27 23:05:06 -07002224
Sebastien Alaiwan41cae6a2018-01-12 12:22:29 +01002225 // Decide q and q bounds.
Angie Chiang958904c2019-09-19 16:03:35 -07002226 *q = av1_rc_pick_q_and_bounds(cpi, &cpi->rc, cm->width, cm->height,
2227 cpi->gf_group.index, bottom_index, top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002228
Yaowu Xuc27fc142016-08-22 16:08:15 -07002229 // Configure experimental use of segmentation for enhanced coding of
2230 // static regions if indicated.
2231 // Only allowed in the second pass of a two pass encode, as it requires
2232 // lagged coding, and if the relevant speed feature flag is set.
chiyotsai6b430132019-12-18 10:33:51 -08002233 if (is_stat_consumption_stage_twopass(cpi) &&
2234 cpi->sf.hl_sf.static_segmentation)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002235 configure_static_seg_features(cpi);
2236}
2237
Yaowu Xuf883b422016-08-30 14:01:10 -07002238static void init_motion_estimation(AV1_COMP *cpi) {
Urvang Joshi510d8f62019-01-10 12:11:50 -08002239 AV1_COMMON *const cm = &cpi->common;
Nithya V Sace29f32020-04-07 16:15:12 +05302240 MotionVectorSearchParams *const mv_search_params = &cpi->mv_search_params;
chiyotsai836b69b2019-04-09 13:41:24 -07002241 const int y_stride = cpi->scaled_source.y_stride;
Vishesh2b8e4792020-06-12 12:11:19 +05302242 const int y_stride_src = ((cpi->oxcf.frm_dim_cfg.width != cm->width ||
2243 cpi->oxcf.frm_dim_cfg.height != cm->height) ||
2244 av1_superres_scaled(cm))
2245 ? y_stride
2246 : cpi->lookahead->buf->img.y_stride;
Mufaddal Chakera975f73a2020-03-31 13:22:25 +05302247 int fpf_y_stride = cm->cur_frame != NULL ? cm->cur_frame->buf.y_stride
2248 : cpi->scaled_source.y_stride;
2249
Cheng Chencaf33512020-04-21 14:54:57 -07002250 // Update if search_site_cfg is uninitialized or the current frame has a new
2251 // stride
Nithya V Sace29f32020-04-07 16:15:12 +05302252 const int should_update =
Cheng Chencaf33512020-04-21 14:54:57 -07002253 !mv_search_params->search_site_cfg[SS_CFG_SRC].stride ||
2254 !mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD].stride ||
2255 (y_stride != mv_search_params->search_site_cfg[SS_CFG_SRC].stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256
chiyotsai836b69b2019-04-09 13:41:24 -07002257 if (!should_update) {
2258 return;
2259 }
2260
chiyotsai8cc054a2019-12-12 14:57:43 -08002261 if (cpi->sf.mv_sf.search_method == DIAMOND) {
Cheng Chencaf33512020-04-21 14:54:57 -07002262 av1_init_dsmotion_compensation(
2263 &mv_search_params->search_site_cfg[SS_CFG_SRC], y_stride);
2264 av1_init_dsmotion_compensation(
2265 &mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD], y_stride_src);
chiyotsai836b69b2019-04-09 13:41:24 -07002266 } else {
Cheng Chencaf33512020-04-21 14:54:57 -07002267 av1_init3smotion_compensation(
2268 &mv_search_params->search_site_cfg[SS_CFG_SRC], y_stride);
2269 av1_init3smotion_compensation(
2270 &mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD], y_stride_src);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002271 }
Cheng Chencaf33512020-04-21 14:54:57 -07002272 av1_init_motion_fpf(&mv_search_params->search_site_cfg[SS_CFG_FPF],
2273 fpf_y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002274}
2275
Debargha Mukherjee84f567c2017-06-21 10:53:59 -07002276#define COUPLED_CHROMA_FROM_LUMA_RESTORATION 0
Rupert Swarbrickbcb65fe2017-10-25 17:15:28 +01002277static void set_restoration_unit_size(int width, int height, int sx, int sy,
2278 RestorationInfo *rst) {
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08002279 (void)width;
2280 (void)height;
Debargha Mukherjee84f567c2017-06-21 10:53:59 -07002281 (void)sx;
2282 (void)sy;
2283#if COUPLED_CHROMA_FROM_LUMA_RESTORATION
2284 int s = AOMMIN(sx, sy);
2285#else
2286 int s = 0;
2287#endif // !COUPLED_CHROMA_FROM_LUMA_RESTORATION
2288
Debargha Mukherjee5f7f3672017-08-12 10:22:49 -07002289 if (width * height > 352 * 288)
Urvang Joshi813186b2018-03-08 15:38:46 -08002290 rst[0].restoration_unit_size = RESTORATION_UNITSIZE_MAX;
Debargha Mukherjee5f7f3672017-08-12 10:22:49 -07002291 else
Urvang Joshi813186b2018-03-08 15:38:46 -08002292 rst[0].restoration_unit_size = (RESTORATION_UNITSIZE_MAX >> 1);
Rupert Swarbrickbcb65fe2017-10-25 17:15:28 +01002293 rst[1].restoration_unit_size = rst[0].restoration_unit_size >> s;
2294 rst[2].restoration_unit_size = rst[1].restoration_unit_size;
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08002295}
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08002296
Ravi Chaudhary783d6a32018-08-28 18:21:02 +05302297static void init_ref_frame_bufs(AV1_COMP *cpi) {
2298 AV1_COMMON *const cm = &cpi->common;
Cheng Chen46f30c72017-09-07 11:13:33 -07002299 int i;
2300 BufferPool *const pool = cm->buffer_pool;
Jack Haughtonddb80602018-11-21 16:41:49 +00002301 cm->cur_frame = NULL;
Cheng Chen46f30c72017-09-07 11:13:33 -07002302 for (i = 0; i < REF_FRAMES; ++i) {
David Turnere7ebf902018-12-04 14:04:55 +00002303 cm->ref_frame_map[i] = NULL;
Wan-Teh Changd05e0332018-10-03 12:00:43 -07002304 }
2305 for (i = 0; i < FRAME_BUFFERS; ++i) {
Cheng Chen46f30c72017-09-07 11:13:33 -07002306 pool->frame_bufs[i].ref_count = 0;
2307 }
Cheng Chen46f30c72017-09-07 11:13:33 -07002308}
2309
Mufaddal Chakera02ac17f2019-12-09 18:09:55 +05302310void av1_check_initial_width(AV1_COMP *cpi, int use_highbitdepth,
2311 int subsampling_x, int subsampling_y) {
Cheng Chen46f30c72017-09-07 11:13:33 -07002312 AV1_COMMON *const cm = &cpi->common;
Urvang Joshi20cf30e2018-07-19 02:33:58 -07002313 SequenceHeader *const seq_params = &cm->seq_params;
Jayasanker J44fdab72020-04-13 20:34:38 +05302314 InitialDimensions *const initial_dimensions = &cpi->initial_dimensions;
Cheng Chen46f30c72017-09-07 11:13:33 -07002315
Jayasanker J44fdab72020-04-13 20:34:38 +05302316 if (!initial_dimensions->width ||
2317 seq_params->use_highbitdepth != use_highbitdepth ||
Urvang Joshi20cf30e2018-07-19 02:33:58 -07002318 seq_params->subsampling_x != subsampling_x ||
2319 seq_params->subsampling_y != subsampling_y) {
2320 seq_params->subsampling_x = subsampling_x;
2321 seq_params->subsampling_y = subsampling_y;
2322 seq_params->use_highbitdepth = use_highbitdepth;
Cheng Chen46f30c72017-09-07 11:13:33 -07002323
Jingning Han183b2a82019-12-18 16:03:41 -08002324 av1_set_speed_features_framesize_independent(cpi, cpi->oxcf.speed);
2325 av1_set_speed_features_framesize_dependent(cpi, cpi->oxcf.speed);
2326
Mufaddal Chakera975f73a2020-03-31 13:22:25 +05302327 if (!is_stat_generation_stage(cpi)) {
2328 alloc_altref_frame_buffer(cpi);
2329 alloc_util_frame_buffers(cpi);
2330 }
Ravi Chaudhary783d6a32018-08-28 18:21:02 +05302331 init_ref_frame_bufs(cpi);
Cheng Chen46f30c72017-09-07 11:13:33 -07002332
2333 init_motion_estimation(cpi); // TODO(agrange) This can be removed.
2334
Jayasanker J44fdab72020-04-13 20:34:38 +05302335 initial_dimensions->width = cm->width;
2336 initial_dimensions->height = cm->height;
Urvang Joshi9dc909d2020-03-23 16:07:02 -07002337 cpi->initial_mbs = cm->mi_params.MBs;
Cheng Chen46f30c72017-09-07 11:13:33 -07002338 }
2339}
2340
2341// Returns 1 if the assigned width or height was <= 0.
Marco Paniconi63971322019-08-15 21:32:05 -07002342int av1_set_size_literal(AV1_COMP *cpi, int width, int height) {
Cheng Chen46f30c72017-09-07 11:13:33 -07002343 AV1_COMMON *cm = &cpi->common;
Jayasanker J44fdab72020-04-13 20:34:38 +05302344 InitialDimensions *const initial_dimensions = &cpi->initial_dimensions;
Mufaddal Chakera02ac17f2019-12-09 18:09:55 +05302345 av1_check_initial_width(cpi, cm->seq_params.use_highbitdepth,
2346 cm->seq_params.subsampling_x,
2347 cm->seq_params.subsampling_y);
Cheng Chen46f30c72017-09-07 11:13:33 -07002348
2349 if (width <= 0 || height <= 0) return 1;
2350
2351 cm->width = width;
Cheng Chen46f30c72017-09-07 11:13:33 -07002352 cm->height = height;
Debargha Mukherjeeccb27262017-09-25 14:19:46 -07002353
Jayasanker J44fdab72020-04-13 20:34:38 +05302354 if (initial_dimensions->width && initial_dimensions->height &&
2355 (cm->width > initial_dimensions->width ||
2356 cm->height > initial_dimensions->height)) {
Debargha Mukherjeeccb27262017-09-25 14:19:46 -07002357 av1_free_context_buffers(cm);
Yue Cheneb628982019-08-29 15:17:13 -07002358 av1_free_shared_coeff_buffer(&cpi->td.shared_coeff_buf);
2359 av1_free_sms_tree(&cpi->td);
Mufaddal Chakera6c3b6de2020-04-29 12:27:42 +05302360 av1_free_pmc(cpi->td.firstpass_ctx, av1_num_planes(cm));
2361 cpi->td.firstpass_ctx = NULL;
Debargha Mukherjeeccb27262017-09-25 14:19:46 -07002362 alloc_compressor_data(cpi);
2363 realloc_segmentation_maps(cpi);
Jayasanker J44fdab72020-04-13 20:34:38 +05302364 initial_dimensions->width = initial_dimensions->height = 0;
Cheng Chen46f30c72017-09-07 11:13:33 -07002365 }
Cheng Chen46f30c72017-09-07 11:13:33 -07002366 update_frame_size(cpi);
2367
2368 return 0;
2369}
2370
David Turner475a3132019-01-18 15:17:17 +00002371void av1_set_frame_size(AV1_COMP *cpi, int width, int height) {
Fergus Simpsonbc189932017-05-16 17:02:39 -07002372 AV1_COMMON *const cm = &cpi->common;
Urvang Joshi20cf30e2018-07-19 02:33:58 -07002373 const SequenceHeader *const seq_params = &cm->seq_params;
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00002374 const int num_planes = av1_num_planes(cm);
Fergus Simpsonbc189932017-05-16 17:02:39 -07002375 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07002376 int ref_frame;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002377
Fergus Simpsonbc189932017-05-16 17:02:39 -07002378 if (width != cm->width || height != cm->height) {
Fergus Simpson3502d082017-04-10 12:25:07 -07002379 // There has been a change in the encoded frame size
Marco Paniconi63971322019-08-15 21:32:05 -07002380 av1_set_size_literal(cpi, width, height);
Urvang Joshic8b52d52018-03-23 13:16:51 -07002381 // Recalculate 'all_lossless' in case super-resolution was (un)selected.
Urvang Joshib6409e92020-03-23 11:23:27 -07002382 cm->features.all_lossless =
2383 cm->features.coded_lossless && !av1_superres_scaled(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002384 }
Yunqing Wang4b7bf402020-01-28 15:20:53 -08002385 set_mv_search_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002386
Hamsalekha S37cc1d12019-12-12 19:27:41 +05302387 if (is_stat_consumption_stage(cpi)) {
Debargha Mukherjee7166f222017-09-05 21:32:42 -07002388 av1_set_target_rate(cpi, cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002389 }
2390
David Turnere7ebf902018-12-04 14:04:55 +00002391 alloc_frame_mvs(cm, cm->cur_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002392
Cherma Rajan A71d20db2018-04-27 11:15:32 +05302393 // Allocate above context buffers
Urvang Joshi5c8625a2020-03-30 13:16:37 -07002394 CommonContexts *const above_contexts = &cm->above_contexts;
2395 if (above_contexts->num_planes < av1_num_planes(cm) ||
2396 above_contexts->num_mi_cols < cm->mi_params.mi_cols ||
2397 above_contexts->num_tile_rows < cm->tiles.rows) {
2398 av1_free_above_context_buffers(above_contexts);
2399 if (av1_alloc_above_context_buffers(above_contexts, cm->tiles.rows,
2400 cm->mi_params.mi_cols,
2401 av1_num_planes(cm)))
Cherma Rajan A71d20db2018-04-27 11:15:32 +05302402 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
2403 "Failed to allocate context buffers");
2404 }
2405
Yaowu Xuc27fc142016-08-22 16:08:15 -07002406 // Reset the frame pointers to the current frame size.
Urvang Joshi20cf30e2018-07-19 02:33:58 -07002407 if (aom_realloc_frame_buffer(
Jack Haughtonddb80602018-11-21 16:41:49 +00002408 &cm->cur_frame->buf, cm->width, cm->height, seq_params->subsampling_x,
2409 seq_params->subsampling_y, seq_params->use_highbitdepth,
Urvang Joshi6237b882020-03-26 15:02:26 -07002410 cpi->oxcf.border_in_pixels, cm->features.byte_alignment, NULL, NULL,
2411 NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07002412 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413 "Failed to allocate frame buffer");
2414
Rupert Swarbrickf88bc042017-10-18 10:45:51 +01002415 const int frame_width = cm->superres_upscaled_width;
2416 const int frame_height = cm->superres_upscaled_height;
Urvang Joshi20cf30e2018-07-19 02:33:58 -07002417 set_restoration_unit_size(frame_width, frame_height,
2418 seq_params->subsampling_x,
2419 seq_params->subsampling_y, cm->rst_info);
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00002420 for (int i = 0; i < num_planes; ++i)
Rupert Swarbrick1a96c3f2017-10-24 11:55:00 +01002421 cm->rst_info[i].frame_restoration_type = RESTORE_NONE;
Rupert Swarbrickf88bc042017-10-18 10:45:51 +01002422
2423 av1_alloc_restoration_buffers(cm);
Mufaddal Chakera975f73a2020-03-31 13:22:25 +05302424 if (!is_stat_generation_stage(cpi)) alloc_util_frame_buffers(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002425 init_motion_estimation(cpi);
2426
2427 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
David Turnera21966b2018-12-05 14:48:49 +00002428 RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
David Turnere7ebf902018-12-04 14:04:55 +00002429 if (buf != NULL) {
David Turnera21966b2018-12-05 14:48:49 +00002430 struct scale_factors *sf = get_ref_scale_factors(cm, ref_frame);
2431 av1_setup_scale_factors_for_frame(sf, buf->buf.y_crop_width,
David Turner1bcefb32018-11-19 17:54:00 +00002432 buf->buf.y_crop_height, cm->width,
Debargha Mukherjeee242a812018-03-07 21:43:09 -08002433 cm->height);
David Turnera21966b2018-12-05 14:48:49 +00002434 if (av1_is_scaled(sf)) aom_extend_frame_borders(&buf->buf, num_planes);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002435 }
2436 }
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07002437
Hui Su5ebd8702018-01-08 18:09:20 -08002438 av1_setup_scale_factors_for_frame(&cm->sf_identity, cm->width, cm->height,
Debargha Mukherjeee242a812018-03-07 21:43:09 -08002439 cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002440
2441 set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
2442}
2443
Yue Chen2d8405c2020-06-10 14:42:05 -07002444/*!\brief Select and apply cdef filters and switchable restoration filters
2445 *
2446 * \ingroup high_level_algo
Yue Chen2d8405c2020-06-10 14:42:05 -07002447 */
Yue Chen92271e12019-07-09 16:28:02 -07002448static void cdef_restoration_frame(AV1_COMP *cpi, AV1_COMMON *cm,
2449 MACROBLOCKD *xd, int use_restoration,
2450 int use_cdef) {
Deepa K G74de2a02020-04-11 13:09:11 +05302451 MultiThreadInfo *const mt_info = &cpi->mt_info;
2452 const int num_workers = mt_info->num_workers;
logangwf95c9162019-02-20 12:02:32 -08002453 if (use_restoration)
David Turnerc29e1a92018-12-06 14:10:14 +00002454 av1_loop_restoration_save_boundary_lines(&cm->cur_frame->buf, cm, 0);
Ola Hugosson1e7f2d02017-09-22 21:36:26 +02002455
logangwf95c9162019-02-20 12:02:32 -08002456 if (use_cdef) {
Yunqing Wangd1f32e62019-02-20 10:37:51 -08002457#if CONFIG_COLLECT_COMPONENT_TIMING
2458 start_timing(cpi, cdef_time);
2459#endif
Steinar Midtskogen59782122017-07-20 08:49:43 +02002460 // Find CDEF parameters
David Turnerc29e1a92018-12-06 14:10:14 +00002461 av1_cdef_search(&cm->cur_frame->buf, cpi->source, cm, xd,
chiyotsaid2f7b412019-12-18 10:16:42 -08002462 cpi->sf.lpf_sf.cdef_pick_method, cpi->td.mb.rdmult);
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07002463
2464 // Apply the filter
David Turnerc29e1a92018-12-06 14:10:14 +00002465 av1_cdef_frame(&cm->cur_frame->buf, cm, xd);
Yunqing Wangd1f32e62019-02-20 10:37:51 -08002466#if CONFIG_COLLECT_COMPONENT_TIMING
2467 end_timing(cpi, cdef_time);
2468#endif
logangwf95c9162019-02-20 12:02:32 -08002469 } else {
2470 cm->cdef_info.cdef_bits = 0;
2471 cm->cdef_info.cdef_strengths[0] = 0;
2472 cm->cdef_info.nb_cdef_strengths = 1;
2473 cm->cdef_info.cdef_uv_strengths[0] = 0;
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07002474 }
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07002475
Satish Kumar Suman7a5f5f42020-06-09 14:20:47 +05302476 av1_superres_post_encode(cpi);
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07002477
Yunqing Wangd1f32e62019-02-20 10:37:51 -08002478#if CONFIG_COLLECT_COMPONENT_TIMING
2479 start_timing(cpi, loop_restoration_time);
2480#endif
logangwf95c9162019-02-20 12:02:32 -08002481 if (use_restoration) {
David Turnerc29e1a92018-12-06 14:10:14 +00002482 av1_loop_restoration_save_boundary_lines(&cm->cur_frame->buf, cm, 1);
Yaowu Xu35ee2342017-11-08 11:50:46 -08002483 av1_pick_filter_restoration(cpi->source, cpi);
2484 if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
2485 cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
2486 cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
Deepa K G74de2a02020-04-11 13:09:11 +05302487 if (num_workers > 1)
2488 av1_loop_restoration_filter_frame_mt(
2489 &cm->cur_frame->buf, cm, 0, mt_info->workers, num_workers,
2490 &mt_info->lr_row_sync, &cpi->lr_ctxt);
Ravi Chaudharye2aa4012018-06-04 14:20:00 +05302491 else
David Turnerc29e1a92018-12-06 14:10:14 +00002492 av1_loop_restoration_filter_frame(&cm->cur_frame->buf, cm, 0,
Ravi Chaudharye2aa4012018-06-04 14:20:00 +05302493 &cpi->lr_ctxt);
Yaowu Xu35ee2342017-11-08 11:50:46 -08002494 }
logangwf95c9162019-02-20 12:02:32 -08002495 } else {
2496 cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
2497 cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
2498 cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07002499 }
Yunqing Wangd1f32e62019-02-20 10:37:51 -08002500#if CONFIG_COLLECT_COMPONENT_TIMING
2501 end_timing(cpi, loop_restoration_time);
2502#endif
Fergus Simpsonbc189932017-05-16 17:02:39 -07002503}
2504
Yue Chen2d8405c2020-06-10 14:42:05 -07002505/*!\brief Select and apply in-loop deblocking filters, cdef filters, and
2506 * restoration filters
2507 *
2508 * \ingroup high_level_algo
Yue Chen2d8405c2020-06-10 14:42:05 -07002509 */
Yue Chen92271e12019-07-09 16:28:02 -07002510static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
Deepa K G74de2a02020-04-11 13:09:11 +05302511 MultiThreadInfo *const mt_info = &cpi->mt_info;
2512 const int num_workers = mt_info->num_workers;
Yue Chen92271e12019-07-09 16:28:02 -07002513 const int num_planes = av1_num_planes(cm);
2514 MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
2515
Vishesh39e74092020-06-16 17:13:48 +05302516 assert(IMPLIES(is_lossless_requested(&cpi->oxcf.rc_cfg),
Urvang Joshib6409e92020-03-23 11:23:27 -07002517 cm->features.coded_lossless && cm->features.all_lossless));
Yue Chen92271e12019-07-09 16:28:02 -07002518
Urvang Joshib6409e92020-03-23 11:23:27 -07002519 const int use_loopfilter =
Urvang Joshi54ffae72020-03-23 13:37:10 -07002520 !cm->features.coded_lossless && !cm->tiles.large_scale;
Urvang Joshib6409e92020-03-23 11:23:27 -07002521 const int use_cdef = cm->seq_params.enable_cdef &&
Urvang Joshi54ffae72020-03-23 13:37:10 -07002522 !cm->features.coded_lossless && !cm->tiles.large_scale;
Yue Chen92271e12019-07-09 16:28:02 -07002523 const int use_restoration = cm->seq_params.enable_restoration &&
Urvang Joshib6409e92020-03-23 11:23:27 -07002524 !cm->features.all_lossless &&
Urvang Joshi54ffae72020-03-23 13:37:10 -07002525 !cm->tiles.large_scale;
Yue Chen92271e12019-07-09 16:28:02 -07002526
2527 struct loopfilter *lf = &cm->lf;
2528
2529#if CONFIG_COLLECT_COMPONENT_TIMING
2530 start_timing(cpi, loop_filter_time);
2531#endif
2532 if (use_loopfilter) {
2533 aom_clear_system_state();
chiyotsaid2f7b412019-12-18 10:16:42 -08002534 av1_pick_filter_level(cpi->source, cpi, cpi->sf.lpf_sf.lpf_pick);
Yue Chen92271e12019-07-09 16:28:02 -07002535 } else {
2536 lf->filter_level[0] = 0;
2537 lf->filter_level[1] = 0;
2538 }
2539
2540 if (lf->filter_level[0] || lf->filter_level[1]) {
Deepa K G74de2a02020-04-11 13:09:11 +05302541 if (num_workers > 1)
Yue Chen92271e12019-07-09 16:28:02 -07002542 av1_loop_filter_frame_mt(&cm->cur_frame->buf, cm, xd, 0, num_planes, 0,
2543#if CONFIG_LPF_MASK
2544 0,
2545#endif
Deepa K G74de2a02020-04-11 13:09:11 +05302546 mt_info->workers, num_workers,
2547 &mt_info->lf_row_sync);
Yue Chen92271e12019-07-09 16:28:02 -07002548 else
2549 av1_loop_filter_frame(&cm->cur_frame->buf, cm, xd,
2550#if CONFIG_LPF_MASK
2551 0,
2552#endif
2553 0, num_planes, 0);
2554 }
2555#if CONFIG_COLLECT_COMPONENT_TIMING
2556 end_timing(cpi, loop_filter_time);
2557#endif
2558
2559 cdef_restoration_frame(cpi, cm, xd, use_restoration, use_cdef);
2560}
2561
David Turnerf2b334c2018-12-13 13:00:55 +00002562static void fix_interp_filter(InterpFilter *const interp_filter,
2563 const FRAME_COUNTS *const counts) {
2564 if (*interp_filter == SWITCHABLE) {
2565 // Check to see if only one of the filters is actually used
2566 int count[SWITCHABLE_FILTERS] = { 0 };
2567 int num_filters_used = 0;
2568 for (int i = 0; i < SWITCHABLE_FILTERS; ++i) {
2569 for (int j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
2570 count[i] += counts->switchable_interp[j][i];
2571 num_filters_used += (count[i] > 0);
2572 }
2573 if (num_filters_used == 1) {
2574 // Only one filter is used. So set the filter at frame level
2575 for (int i = 0; i < SWITCHABLE_FILTERS; ++i) {
2576 if (count[i]) {
2577 if (i == EIGHTTAP_REGULAR) *interp_filter = i;
2578 break;
2579 }
2580 }
2581 }
2582 }
2583}
2584
David Turner996b2c12018-12-07 15:52:30 +00002585static void finalize_encoded_frame(AV1_COMP *const cpi) {
2586 AV1_COMMON *const cm = &cpi->common;
David Turner99e990e2018-12-10 12:54:26 +00002587 CurrentFrame *const current_frame = &cm->current_frame;
David Turner996b2c12018-12-07 15:52:30 +00002588
David Turner99e990e2018-12-10 12:54:26 +00002589 if (!cm->seq_params.reduced_still_picture_hdr &&
2590 encode_show_existing_frame(cm)) {
2591 RefCntBuffer *const frame_to_show =
2592 cm->ref_frame_map[cpi->existing_fb_idx_to_show];
2593
Wan-Teh Chang88cd1662019-01-14 12:38:41 -08002594 if (frame_to_show == NULL) {
David Turner99e990e2018-12-10 12:54:26 +00002595 aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
2596 "Buffer does not contain a reconstructed frame");
2597 }
Wan-Teh Chang88cd1662019-01-14 12:38:41 -08002598 assert(frame_to_show->ref_count > 0);
David Turner99e990e2018-12-10 12:54:26 +00002599 assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
David Turner99e990e2018-12-10 12:54:26 +00002600 }
David Turner08f909c2018-12-18 13:29:14 +00002601
2602 if (!encode_show_existing_frame(cm) &&
2603 cm->seq_params.film_grain_params_present &&
2604 (cm->show_frame || cm->showable_frame)) {
2605 // Copy the current frame's film grain params to the its corresponding
2606 // RefCntBuffer slot.
2607 cm->cur_frame->film_grain_params = cm->film_grain_params;
2608
2609 // We must update the parameters if this is not an INTER_FRAME
2610 if (current_frame->frame_type != INTER_FRAME)
2611 cm->cur_frame->film_grain_params.update_parameters = 1;
2612
2613 // Iterate the random seed for the next frame.
2614 cm->film_grain_params.random_seed += 3381;
2615 if (cm->film_grain_params.random_seed == 0)
2616 cm->film_grain_params.random_seed = 7391;
2617 }
David Turnerf2b334c2018-12-13 13:00:55 +00002618
2619 // Initialise all tiles' contexts from the global frame context
Urvang Joshi54ffae72020-03-23 13:37:10 -07002620 for (int tile_col = 0; tile_col < cm->tiles.cols; tile_col++) {
2621 for (int tile_row = 0; tile_row < cm->tiles.rows; tile_row++) {
2622 const int tile_idx = tile_row * cm->tiles.cols + tile_col;
David Turnerf2b334c2018-12-13 13:00:55 +00002623 cpi->tile_data[tile_idx].tctx = *cm->fc;
2624 }
2625 }
2626
Urvang Joshi6237b882020-03-26 15:02:26 -07002627 fix_interp_filter(&cm->features.interp_filter, cpi->td.counts);
David Turner996b2c12018-12-07 15:52:30 +00002628}
2629
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002630#if !CONFIG_REALTIME_ONLY
Satish Kumar Suman829c1682019-07-31 11:30:07 +05302631static int get_interp_filter_selected(const AV1_COMMON *const cm,
2632 MV_REFERENCE_FRAME ref,
2633 InterpFilter ifilter) {
2634 const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
2635 if (buf == NULL) return 0;
2636 return buf->interp_filter_selected[ifilter];
2637}
2638
Satish Kumar Suman0389a492019-07-31 13:35:58 +05302639static uint16_t setup_interp_filter_search_mask(AV1_COMP *cpi) {
Satish Kumar Suman829c1682019-07-31 11:30:07 +05302640 const AV1_COMMON *const cm = &cpi->common;
2641 int ref_total[REF_FRAMES] = { 0 };
Satish Kumar Suman0389a492019-07-31 13:35:58 +05302642 uint16_t mask = ALLOW_ALL_INTERP_FILT_MASK;
Satish Kumar Suman829c1682019-07-31 11:30:07 +05302643
Jayasanker J24cb9bc2020-04-15 13:43:10 +05302644 if (cpi->last_frame_type == KEY_FRAME || cpi->refresh_frame.alt_ref_frame)
Satish Kumar Suman0389a492019-07-31 13:35:58 +05302645 return mask;
Satish Kumar Suman829c1682019-07-31 11:30:07 +05302646
2647 for (MV_REFERENCE_FRAME ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
2648 for (InterpFilter ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP;
2649 ++ifilter) {
2650 ref_total[ref] += get_interp_filter_selected(cm, ref, ifilter);
2651 }
2652 }
2653 int ref_total_total = (ref_total[LAST2_FRAME] + ref_total[LAST3_FRAME] +
2654 ref_total[GOLDEN_FRAME] + ref_total[BWDREF_FRAME] +
2655 ref_total[ALTREF2_FRAME] + ref_total[ALTREF_FRAME]);
2656
Satish Kumar Suman829c1682019-07-31 11:30:07 +05302657 for (InterpFilter ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP;
2658 ++ifilter) {
2659 int last_score = get_interp_filter_selected(cm, LAST_FRAME, ifilter) * 30;
2660 if (ref_total[LAST_FRAME] && last_score <= ref_total[LAST_FRAME]) {
2661 int filter_score =
2662 get_interp_filter_selected(cm, LAST2_FRAME, ifilter) * 20 +
2663 get_interp_filter_selected(cm, LAST3_FRAME, ifilter) * 20 +
2664 get_interp_filter_selected(cm, GOLDEN_FRAME, ifilter) * 20 +
2665 get_interp_filter_selected(cm, BWDREF_FRAME, ifilter) * 10 +
2666 get_interp_filter_selected(cm, ALTREF2_FRAME, ifilter) * 10 +
2667 get_interp_filter_selected(cm, ALTREF_FRAME, ifilter) * 10;
Satish Kumar Suman0389a492019-07-31 13:35:58 +05302668 if (filter_score < ref_total_total) {
2669 DUAL_FILTER_TYPE filt_type = ifilter + SWITCHABLE_FILTERS * ifilter;
2670 reset_interp_filter_allowed_mask(&mask, filt_type);
2671 }
Satish Kumar Suman829c1682019-07-31 11:30:07 +05302672 }
2673 }
2674 return mask;
2675}
2676
chiyotsai155e2862020-03-09 15:29:34 -07002677#define STRICT_PSNR_DIFF_THRESH 0.9
Cheng Chen92a926a2020-01-30 17:57:33 -08002678// Encode key frame with/without screen content tools to determine whether
2679// screen content tools should be enabled for this key frame group or not.
2680// The first encoding is without screen content tools.
2681// The second encoding is with screen content tools.
2682// We compare the psnr and frame size to make the decision.
2683static void screen_content_tools_determination(
2684 AV1_COMP *cpi, const int allow_screen_content_tools_orig_decision,
2685 const int allow_intrabc_orig_decision,
2686 const int is_screen_content_type_orig_decision, const int pass,
2687 int *projected_size_pass, PSNR_STATS *psnr) {
2688 AV1_COMMON *const cm = &cpi->common;
Urvang Joshib6409e92020-03-23 11:23:27 -07002689 FeatureFlags *const features = &cm->features;
Cheng Chen92a926a2020-01-30 17:57:33 -08002690 projected_size_pass[pass] = cpi->rc.projected_frame_size;
2691#if CONFIG_AV1_HIGHBITDEPTH
2692 const uint32_t in_bit_depth = cpi->oxcf.input_bit_depth;
2693 const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
2694 aom_calc_highbd_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr[pass],
2695 bit_depth, in_bit_depth);
2696#else
2697 aom_calc_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr[pass]);
2698#endif
2699 if (pass != 1) return;
2700
2701 const double psnr_diff = psnr[1].psnr[0] - psnr[0].psnr[0];
2702 const int is_sc_encoding_much_better = psnr_diff > STRICT_PSNR_DIFF_THRESH;
2703 if (is_sc_encoding_much_better) {
2704 // Use screen content tools, if we get coding gain.
Urvang Joshib6409e92020-03-23 11:23:27 -07002705 features->allow_screen_content_tools = 1;
2706 features->allow_intrabc = cpi->intrabc_used;
Cheng Chen92a926a2020-01-30 17:57:33 -08002707 cpi->is_screen_content_type = 1;
2708 } else {
2709 // Use original screen content decision.
Urvang Joshib6409e92020-03-23 11:23:27 -07002710 features->allow_screen_content_tools =
2711 allow_screen_content_tools_orig_decision;
2712 features->allow_intrabc = allow_intrabc_orig_decision;
Cheng Chen92a926a2020-01-30 17:57:33 -08002713 cpi->is_screen_content_type = is_screen_content_type_orig_decision;
2714 }
2715}
2716
Cheng Chenb8c938b2020-03-23 11:30:18 -07002717// Set some encoding parameters to make the encoding process fast.
2718// A fixed block partition size, and a large q is used.
2719static void set_encoding_params_for_screen_content(AV1_COMP *cpi,
2720 const int pass) {
Cheng Chen92a926a2020-01-30 17:57:33 -08002721 AV1_COMMON *const cm = &cpi->common;
2722 if (pass == 0) {
2723 // In the first pass, encode without screen content tools.
2724 // Use a high q, and a fixed block size for fast encoding.
Urvang Joshib6409e92020-03-23 11:23:27 -07002725 cm->features.allow_screen_content_tools = 0;
2726 cm->features.allow_intrabc = 0;
Cheng Chen92a926a2020-01-30 17:57:33 -08002727 cpi->is_screen_content_type = 0;
2728 cpi->sf.part_sf.partition_search_type = FIXED_PARTITION;
2729 cpi->sf.part_sf.always_this_block_size = BLOCK_32X32;
Cheng Chenb8c938b2020-03-23 11:30:18 -07002730 return;
Cheng Chen92a926a2020-01-30 17:57:33 -08002731 }
Cheng Chenb8c938b2020-03-23 11:30:18 -07002732 assert(pass == 1);
2733 // In the second pass, encode with screen content tools.
2734 // Use a high q, and a fixed block size for fast encoding.
Urvang Joshib6409e92020-03-23 11:23:27 -07002735 cm->features.allow_screen_content_tools = 1;
Cheng Chenb8c938b2020-03-23 11:30:18 -07002736 // TODO(chengchen): turn intrabc on could lead to data race issue.
2737 // cm->allow_intrabc = 1;
2738 cpi->is_screen_content_type = 1;
2739 cpi->sf.part_sf.partition_search_type = FIXED_PARTITION;
2740 cpi->sf.part_sf.always_this_block_size = BLOCK_32X32;
Cheng Chen92a926a2020-01-30 17:57:33 -08002741}
2742
2743// Determines whether to use screen content tools for the key frame group.
Urvang Joshib6409e92020-03-23 11:23:27 -07002744// This function modifies "cm->features.allow_screen_content_tools",
2745// "cm->features.allow_intrabc" and "cpi->is_screen_content_type".
Cheng Chen92a926a2020-01-30 17:57:33 -08002746static void determine_sc_tools_with_encoding(AV1_COMP *cpi, const int q_orig) {
Cheng Chen92a926a2020-01-30 17:57:33 -08002747 AV1_COMMON *const cm = &cpi->common;
Vishesh734eff92020-06-20 21:46:36 +05302748 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2749 const QuantizationCfg *const q_cfg = &oxcf->q_cfg;
Cheng Chen92a926a2020-01-30 17:57:33 -08002750 // Variables to help determine if we should allow screen content tools.
2751 int projected_size_pass[3] = { 0 };
2752 PSNR_STATS psnr[3];
2753 const int is_key_frame = cm->current_frame.frame_type == KEY_FRAME;
2754 const int allow_screen_content_tools_orig_decision =
Urvang Joshib6409e92020-03-23 11:23:27 -07002755 cm->features.allow_screen_content_tools;
2756 const int allow_intrabc_orig_decision = cm->features.allow_intrabc;
Cheng Chen92a926a2020-01-30 17:57:33 -08002757 const int is_screen_content_type_orig_decision = cpi->is_screen_content_type;
2758 // Turn off the encoding trial for forward key frame and superres.
Vishesh734eff92020-06-20 21:46:36 +05302759 if (cpi->sf.rt_sf.use_nonrd_pick_mode || oxcf->kf_cfg.fwd_kf_enabled ||
2760 cpi->superres_mode != AOM_SUPERRES_NONE || oxcf->mode == REALTIME ||
Cheng Chen92a926a2020-01-30 17:57:33 -08002761 is_screen_content_type_orig_decision || !is_key_frame) {
2762 return;
2763 }
2764
2765 // TODO(chengchen): multiple encoding for the lossless mode is time consuming.
2766 // Find a better way to determine whether screen content tools should be used
2767 // for lossless coding.
2768 // Use a high q and a fixed partition to do quick encoding.
2769 const int q_for_screen_content_quick_run =
Vishesh734eff92020-06-20 21:46:36 +05302770 is_lossless_requested(&oxcf->rc_cfg) ? q_orig : AOMMAX(q_orig, 244);
Cheng Chen92a926a2020-01-30 17:57:33 -08002771 const int partition_search_type_orig = cpi->sf.part_sf.partition_search_type;
2772 const BLOCK_SIZE fixed_partition_block_size_orig =
2773 cpi->sf.part_sf.always_this_block_size;
2774
2775 // Setup necessary params for encoding, including frame source, etc.
chiyotsaie6ae98e2020-03-23 13:17:08 -07002776 aom_clear_system_state();
Cheng Chen92a926a2020-01-30 17:57:33 -08002777
chiyotsaie6ae98e2020-03-23 13:17:08 -07002778 cpi->source =
Jerome Jiang790190e2020-06-12 16:47:45 -07002779 av1_scale_if_required(cm, cpi->unscaled_source, &cpi->scaled_source,
2780 cm->features.interp_filter, 0);
chiyotsaie6ae98e2020-03-23 13:17:08 -07002781 if (cpi->unscaled_last_source != NULL) {
2782 cpi->last_source = av1_scale_if_required(cm, cpi->unscaled_last_source,
Jerome Jiang790190e2020-06-12 16:47:45 -07002783 &cpi->scaled_last_source,
2784 cm->features.interp_filter, 0);
Cheng Chen92a926a2020-01-30 17:57:33 -08002785 }
2786
chiyotsaie6ae98e2020-03-23 13:17:08 -07002787 setup_frame(cpi);
2788
2789 if (cm->seg.enabled) {
2790 if (!cm->seg.update_data && cm->prev_frame) {
2791 segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
2792 cm->seg.enabled = cm->prev_frame->seg.enabled;
2793 } else {
2794 av1_calculate_segdata(&cm->seg);
2795 }
2796 } else {
2797 memset(&cm->seg, 0, sizeof(cm->seg));
2798 }
2799 segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
2800 cm->cur_frame->seg.enabled = cm->seg.enabled;
2801
Cheng Chenb8c938b2020-03-23 11:30:18 -07002802 // The two encoding passes aim to help determine whether to use screen
2803 // content tools, with a high q and fixed partition.
Cheng Chen92a926a2020-01-30 17:57:33 -08002804 for (int pass = 0; pass < 2; ++pass) {
Cheng Chenb8c938b2020-03-23 11:30:18 -07002805 set_encoding_params_for_screen_content(cpi, pass);
Cheng Chen92a926a2020-01-30 17:57:33 -08002806#if CONFIG_TUNE_VMAF
Vishesh734eff92020-06-20 21:46:36 +05302807 if (oxcf->tuning == AOM_TUNE_VMAF_WITH_PREPROCESSING ||
2808 oxcf->tuning == AOM_TUNE_VMAF_WITHOUT_PREPROCESSING ||
2809 oxcf->tuning == AOM_TUNE_VMAF_MAX_GAIN) {
Cheng Chen92a926a2020-01-30 17:57:33 -08002810 av1_set_quantizer(
Vishesh734eff92020-06-20 21:46:36 +05302811 cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel,
Yue Chen04e836a2019-07-23 15:04:22 -07002812 av1_get_vmaf_base_qindex(cpi, q_for_screen_content_quick_run),
Vishesh734eff92020-06-20 21:46:36 +05302813 q_cfg->enable_chroma_deltaq);
Cheng Chen92a926a2020-01-30 17:57:33 -08002814 } else {
2815#endif
Vishesh734eff92020-06-20 21:46:36 +05302816 av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel,
Yue Chen04e836a2019-07-23 15:04:22 -07002817 q_for_screen_content_quick_run,
Vishesh734eff92020-06-20 21:46:36 +05302818 q_cfg->enable_chroma_deltaq);
Cheng Chen92a926a2020-01-30 17:57:33 -08002819#if CONFIG_TUNE_VMAF
2820 }
2821#endif
Vishesh734eff92020-06-20 21:46:36 +05302822 av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
2823 if (q_cfg->deltaq_mode != NO_DELTA_Q)
Deepa K Gc0d27832020-04-07 16:52:27 +05302824 av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
2825 cm->seq_params.bit_depth);
Cheng Chen92a926a2020-01-30 17:57:33 -08002826
2827 av1_set_variance_partition_thresholds(cpi, q_for_screen_content_quick_run,
2828 0);
2829 // transform / motion compensation build reconstruction frame
2830 av1_encode_frame(cpi);
2831 // Screen content decision
2832 screen_content_tools_determination(
2833 cpi, allow_screen_content_tools_orig_decision,
2834 allow_intrabc_orig_decision, is_screen_content_type_orig_decision, pass,
2835 projected_size_pass, psnr);
2836 }
2837
2838 // Set partition speed feature back.
2839 cpi->sf.part_sf.partition_search_type = partition_search_type_orig;
2840 cpi->sf.part_sf.always_this_block_size = fixed_partition_block_size_orig;
2841}
2842#endif // CONFIG_REALTIME_ONLY
2843
Yue Chen2d8405c2020-06-10 14:42:05 -07002844/*!\brief Encode a frame without the recode loop, usually used in one-pass
2845 * encoding and realtime coding.
2846 *
2847 * \ingroup high_level_algo
Yue Chen2d8405c2020-06-10 14:42:05 -07002848 *
2849 * \param[in] cpi Top-level encoder structure
2850 *
2851 * \return Returns a value to indicate if the encoding is done successfully.
2852 * \retval #AOM_CODEC_OK
2853 * \retval #AOM_CODEC_ERROR
2854 */
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002855static int encode_without_recode(AV1_COMP *cpi) {
2856 AV1_COMMON *const cm = &cpi->common;
Vishesh734eff92020-06-20 21:46:36 +05302857 const QuantizationCfg *const q_cfg = &cpi->oxcf.q_cfg;
Jerome Jiang790190e2020-06-12 16:47:45 -07002858 SVC *const svc = &cpi->svc;
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002859 int top_index = 0, bottom_index = 0, q = 0;
Jerome Jiang790190e2020-06-12 16:47:45 -07002860 YV12_BUFFER_CONFIG *unscaled = cpi->unscaled_source;
Jerome Jiangdede2932020-06-23 16:49:41 -07002861 InterpFilter filter_scaler =
Jerome Jiang790190e2020-06-12 16:47:45 -07002862 cpi->use_svc ? svc->downsample_filter_type[svc->spatial_layer_id]
2863 : EIGHTTAP_REGULAR;
2864 int phase_scaler =
2865 cpi->use_svc ? svc->downsample_filter_phase[svc->spatial_layer_id] : 0;
Jerome Jiangdede2932020-06-23 16:49:41 -07002866
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002867 set_size_independent_vars(cpi);
2868 av1_setup_frame_size(cpi);
2869 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
2870
Jerome Jiangdede2932020-06-23 16:49:41 -07002871 if (!cpi->use_svc && (cm->width << 1) == unscaled->y_crop_width &&
2872 (cm->height << 1) == unscaled->y_crop_height) {
2873 filter_scaler = BILINEAR;
2874 phase_scaler = 8;
2875 }
2876
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002877 if (cpi->sf.part_sf.partition_search_type == VAR_BASED_PARTITION)
2878 variance_partition_alloc(cpi);
2879
2880 if (cm->current_frame.frame_type == KEY_FRAME) copy_frame_prob_info(cpi);
2881
2882#if CONFIG_COLLECT_COMPONENT_TIMING
2883 printf("\n Encoding a frame:");
2884#endif
Marco Paniconid13853d2020-05-07 11:42:16 -07002885
2886 aom_clear_system_state();
2887
Jerome Jiang790190e2020-06-12 16:47:45 -07002888 cpi->source = av1_scale_if_required(cm, unscaled, &cpi->scaled_source,
Jerome Jiangdede2932020-06-23 16:49:41 -07002889 filter_scaler, phase_scaler);
Marco Paniconid13853d2020-05-07 11:42:16 -07002890 if (cpi->unscaled_last_source != NULL) {
2891 cpi->last_source = av1_scale_if_required(cm, cpi->unscaled_last_source,
Jerome Jiang790190e2020-06-12 16:47:45 -07002892 &cpi->scaled_last_source,
Jerome Jiangdede2932020-06-23 16:49:41 -07002893 filter_scaler, phase_scaler);
Marco Paniconid13853d2020-05-07 11:42:16 -07002894 }
Marco Paniconi2b22a1f2020-06-22 21:55:02 -07002895
2896 // For SVC the inter-layer/spatial prediction is not done for newmv
2897 // (zero_mode is forced), and since the scaled references are only
2898 // use for newmv search, we can avoid scaling here.
2899 if (!frame_is_intra_only(cm) &&
2900 !(cpi->use_svc && cpi->svc.force_zero_mode_spatial_ref))
Jerome Jiangdede2932020-06-23 16:49:41 -07002901 scale_references(cpi, filter_scaler, phase_scaler);
Marco Paniconid13853d2020-05-07 11:42:16 -07002902
Vishesh734eff92020-06-20 21:46:36 +05302903 av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
2904 q_cfg->enable_chroma_deltaq);
Marco Paniconid13853d2020-05-07 11:42:16 -07002905 av1_set_speed_features_qindex_dependent(cpi, cpi->oxcf.speed);
Vishesh734eff92020-06-20 21:46:36 +05302906 if (q_cfg->deltaq_mode != NO_DELTA_Q)
Marco Paniconid13853d2020-05-07 11:42:16 -07002907 av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
2908 cm->seq_params.bit_depth);
2909 av1_set_variance_partition_thresholds(cpi, q, 0);
2910 setup_frame(cpi);
2911
2912 // Check if this high_source_sad (scene/slide change) frame should be
2913 // encoded at high/max QP, and if so, set the q and adjust some rate
2914 // control parameters.
2915 if (cpi->sf.rt_sf.overshoot_detection_cbr == FAST_DETECTION_MAXQ &&
2916 cpi->rc.high_source_sad) {
2917 if (av1_encodedframe_overshoot(cpi, &q)) {
Vishesh734eff92020-06-20 21:46:36 +05302918 av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
2919 q_cfg->enable_chroma_deltaq);
Marco Paniconid13853d2020-05-07 11:42:16 -07002920 av1_set_speed_features_qindex_dependent(cpi, cpi->oxcf.speed);
Vishesh734eff92020-06-20 21:46:36 +05302921 if (q_cfg->deltaq_mode != NO_DELTA_Q)
Marco Paniconid13853d2020-05-07 11:42:16 -07002922 av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
2923 cm->seq_params.bit_depth);
2924 av1_set_variance_partition_thresholds(cpi, q, 0);
2925 }
2926 }
2927
Vishesh734eff92020-06-20 21:46:36 +05302928 if (q_cfg->aq_mode == CYCLIC_REFRESH_AQ) {
Marco Paniconid13853d2020-05-07 11:42:16 -07002929 suppress_active_map(cpi);
2930 av1_cyclic_refresh_setup(cpi);
2931 apply_active_map(cpi);
2932 }
2933 if (cm->seg.enabled) {
2934 if (!cm->seg.update_data && cm->prev_frame) {
2935 segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
2936 cm->seg.enabled = cm->prev_frame->seg.enabled;
2937 } else {
2938 av1_calculate_segdata(&cm->seg);
2939 }
2940 } else {
2941 memset(&cm->seg, 0, sizeof(cm->seg));
2942 }
2943 segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
2944 cm->cur_frame->seg.enabled = cm->seg.enabled;
2945
2946#if CONFIG_COLLECT_COMPONENT_TIMING
2947 start_timing(cpi, av1_encode_frame_time);
2948#endif
2949
2950 // Set the motion vector precision based on mv stats from the last coded
2951 // frame.
2952 if (!frame_is_intra_only(cm)) av1_pick_and_set_high_precision_mv(cpi, q);
2953
2954 // transform / motion compensation build reconstruction frame
2955 av1_encode_frame(cpi);
2956
2957 // Update some stats from cyclic refresh.
Vishesh734eff92020-06-20 21:46:36 +05302958 if (q_cfg->aq_mode == CYCLIC_REFRESH_AQ && !frame_is_intra_only(cm))
Marco Paniconid13853d2020-05-07 11:42:16 -07002959 av1_cyclic_refresh_postencode(cpi);
2960
2961#if CONFIG_COLLECT_COMPONENT_TIMING
2962 end_timing(cpi, av1_encode_frame_time);
2963#endif
2964#if CONFIG_INTERNAL_STATS
2965 ++cpi->tot_recode_hits;
2966#endif
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002967
Marco Paniconie635eb62020-05-14 14:01:02 -07002968 aom_clear_system_state();
2969
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002970 return AOM_CODEC_OK;
Marco Paniconid13853d2020-05-07 11:42:16 -07002971}
2972
Marco Paniconic6cd72e2020-05-08 11:00:50 -07002973#if !CONFIG_REALTIME_ONLY
Yue Chen2d8405c2020-06-10 14:42:05 -07002974
2975/*!\brief Recode loop for encoding one frame. the purpose of encoding one frame
2976 * for multiple times can be approaching a target bitrate or adjusting the usage
2977 * of global motions.
2978 *
2979 * \ingroup high_level_algo
Yue Chen2d8405c2020-06-10 14:42:05 -07002980 *
2981 * \param[in] cpi Top-level encoder structure
2982 * \param[in] size Bitstream size
2983 * \param[in] dest Bitstream output
2984 *
2985 * \return Returns a value to indicate if the encoding is done successfully.
2986 * \retval #AOM_CODEC_OK
2987 * \retval -1
2988 * \retval #AOM_CODEC_ERROR
2989 */
Tom Finegane4099e32018-01-23 12:01:51 -08002990static int encode_with_recode_loop(AV1_COMP *cpi, size_t *size, uint8_t *dest) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002991 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002992 RATE_CONTROL *const rc = &cpi->rc;
Vishesh8ba8bfe2020-04-03 14:20:29 +05302993 GlobalMotionInfo *const gm_info = &cpi->gm_info;
Vishesh734eff92020-06-20 21:46:36 +05302994 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2995 const QuantizationCfg *const q_cfg = &oxcf->q_cfg;
chiyotsai6b430132019-12-18 10:33:51 -08002996 const int allow_recode = (cpi->sf.hl_sf.recode_loop != DISALLOW_RECODE);
Hui Sua1d71842019-07-31 12:02:24 -07002997 // Must allow recode if minimum compression ratio is set.
Vishesh734eff92020-06-20 21:46:36 +05302998 assert(IMPLIES(oxcf->rc_cfg.min_cr > 0, allow_recode));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002999
3000 set_size_independent_vars(cpi);
Hamsalekha S37cc1d12019-12-12 19:27:41 +05303001 if (is_stat_consumption_stage_twopass(cpi) &&
chiyotsaicbf1d112019-12-16 11:28:47 -08003002 cpi->sf.interp_sf.adaptive_interp_filter_search)
Jayasanker Je0bbb432020-04-08 18:16:18 +05303003 cpi->interp_search_flags.interp_filter_search_mask =
3004 setup_interp_filter_search_mask(cpi);
Yaowu Xu9b0f7032017-07-31 11:01:19 -07003005 cpi->source->buf_8bit_valid = 0;
Yaowu Xu9b0f7032017-07-31 11:01:19 -07003006
David Turnerdedd8ff2019-01-23 13:59:46 +00003007 av1_setup_frame_size(cpi);
Debargha Mukherjee7166f222017-09-05 21:32:42 -07003008
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003009#if CONFIG_SUPERRES_IN_RECODE
Satish Kumar Suman7a5f5f42020-06-09 14:20:47 +05303010 if (av1_superres_in_recode_allowed(cpi) &&
Urvang Joshi9d2606c2020-04-14 15:58:01 -07003011 cpi->superres_mode != AOM_SUPERRES_NONE &&
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003012 cm->superres_scale_denominator == SCALE_NUMERATOR) {
Urvang Joshidb4551e2020-04-08 12:30:21 -07003013 // Superres mode is currently enabled, but the denominator selected will
Urvang Joshif9c2bd72020-04-07 15:11:51 -07003014 // disable superres. So no need to continue, as we will go through another
3015 // recode loop for full-resolution after this anyway.
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003016 return -1;
3017 }
3018#endif // CONFIG_SUPERRES_IN_RECODE
3019
David Turner2f3b5df2019-01-02 14:30:50 +00003020 int top_index = 0, bottom_index = 0;
3021 int q = 0, q_low = 0, q_high = 0;
3022 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
3023 q_low = bottom_index;
3024 q_high = top_index;
3025
Marco Paniconic6cd72e2020-05-08 11:00:50 -07003026 if (cpi->sf.part_sf.partition_search_type == VAR_BASED_PARTITION)
3027 variance_partition_alloc(cpi);
Vishesh2770b972020-04-08 13:49:55 +05303028
Marco Paniconic6cd72e2020-05-08 11:00:50 -07003029 if (cm->current_frame.frame_type == KEY_FRAME) copy_frame_prob_info(cpi);
Cheng Chen92a926a2020-01-30 17:57:33 -08003030
3031#if CONFIG_COLLECT_COMPONENT_TIMING
3032 printf("\n Encoding a frame:");
3033#endif
3034
Marco Paniconid13853d2020-05-07 11:42:16 -07003035 // Determine whether to use screen content tools using two fast encoding.
3036 determine_sc_tools_with_encoding(cpi, q);
Marco Paniconid13853d2020-05-07 11:42:16 -07003037
David Turner2f3b5df2019-01-02 14:30:50 +00003038 // Loop variables
Cheng Chen92a926a2020-01-30 17:57:33 -08003039 int loop = 0;
David Turner2f3b5df2019-01-02 14:30:50 +00003040 int loop_count = 0;
3041 int loop_at_this_size = 0;
David Turner2f3b5df2019-01-02 14:30:50 +00003042 int overshoot_seen = 0;
3043 int undershoot_seen = 0;
Hui Suef139e12019-05-20 15:51:22 -07003044 int low_cr_seen = 0;
chiyotsai8b7cef82020-01-21 16:52:54 -08003045 int last_loop_allow_hp = 0;
Yunqing Wangd1f32e62019-02-20 10:37:51 -08003046
Yaowu Xuc27fc142016-08-22 16:08:15 -07003047 do {
Debargha Mukherjee9b70d1f2019-05-07 18:34:45 -07003048 loop = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07003049 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003050
Urvang Joshif1fa6862018-01-08 16:39:33 -08003051 // if frame was scaled calculate global_motion_search again if already
3052 // done
Vishesh8ba8bfe2020-04-03 14:20:29 +05303053 if (loop_count > 0 && cpi->source && gm_info->search_done) {
Debargha Mukherjeeccb27262017-09-25 14:19:46 -07003054 if (cpi->source->y_crop_width != cm->width ||
David Turner2f3b5df2019-01-02 14:30:50 +00003055 cpi->source->y_crop_height != cm->height) {
Vishesh8ba8bfe2020-04-03 14:20:29 +05303056 gm_info->search_done = 0;
David Turner2f3b5df2019-01-02 14:30:50 +00003057 }
3058 }
Jerome Jiangdede2932020-06-23 16:49:41 -07003059 cpi->source = av1_scale_if_required(
3060 cm, cpi->unscaled_source, &cpi->scaled_source, EIGHTTAP_REGULAR, 0);
3061
David Turner2f3b5df2019-01-02 14:30:50 +00003062 if (cpi->unscaled_last_source != NULL) {
Jerome Jiangdede2932020-06-23 16:49:41 -07003063 cpi->last_source =
3064 av1_scale_if_required(cm, cpi->unscaled_last_source,
3065 &cpi->scaled_last_source, EIGHTTAP_REGULAR, 0);
David Turner2f3b5df2019-01-02 14:30:50 +00003066 }
Debargha Mukherjee17e7b082017-08-13 09:33:03 -07003067
David Turner2f3b5df2019-01-02 14:30:50 +00003068 if (!frame_is_intra_only(cm)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003069 if (loop_count > 0) {
3070 release_scaled_references(cpi);
3071 }
Jerome Jiangdede2932020-06-23 16:49:41 -07003072 scale_references(cpi, EIGHTTAP_REGULAR, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003073 }
sdeng3cd9eec2020-01-23 15:49:50 -08003074#if CONFIG_TUNE_VMAF
Vishesh734eff92020-06-20 21:46:36 +05303075 if (oxcf->tuning == AOM_TUNE_VMAF_WITH_PREPROCESSING ||
3076 oxcf->tuning == AOM_TUNE_VMAF_WITHOUT_PREPROCESSING ||
3077 oxcf->tuning == AOM_TUNE_VMAF_MAX_GAIN) {
3078 av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel,
Yue Chen04e836a2019-07-23 15:04:22 -07003079 av1_get_vmaf_base_qindex(cpi, q),
Vishesh734eff92020-06-20 21:46:36 +05303080 q_cfg->enable_chroma_deltaq);
sdeng3cd9eec2020-01-23 15:49:50 -08003081 } else {
3082#endif
Vishesh734eff92020-06-20 21:46:36 +05303083 av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
3084 q_cfg->enable_chroma_deltaq);
sdeng3cd9eec2020-01-23 15:49:50 -08003085#if CONFIG_TUNE_VMAF
3086 }
3087#endif
Vishesh734eff92020-06-20 21:46:36 +05303088 av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
sdeng3cd9eec2020-01-23 15:49:50 -08003089
Vishesh734eff92020-06-20 21:46:36 +05303090 if (q_cfg->deltaq_mode != NO_DELTA_Q)
Deepa K Gc0d27832020-04-07 16:52:27 +05303091 av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
3092 cm->seq_params.bit_depth);
kyslov7b9d0d62018-12-21 11:12:26 -08003093
3094 av1_set_variance_partition_thresholds(cpi, q, 0);
3095
Debargha Mukherjeef48b0d22018-11-20 12:23:43 -08003096 // printf("Frame %d/%d: q = %d, frame_type = %d superres_denom = %d\n",
3097 // cm->current_frame.frame_number, cm->show_frame, q,
3098 // cm->current_frame.frame_type, cm->superres_scale_denominator);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003099
David Turner2f3b5df2019-01-02 14:30:50 +00003100 if (loop_count == 0) {
3101 setup_frame(cpi);
3102 } else if (get_primary_ref_frame_buf(cm) == NULL) {
3103 // Base q-index may have changed, so we need to assign proper default coef
3104 // probs before every iteration.
Yaowu Xuf883b422016-08-30 14:01:10 -07003105 av1_default_coef_probs(cm);
Hui Su3694c832017-11-10 14:15:58 -08003106 av1_setup_frame_contexts(cm);
David Barkerfc91b392018-03-09 15:32:03 +00003107 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003108
Vishesh734eff92020-06-20 21:46:36 +05303109 if (q_cfg->aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003110 av1_vaq_frame_setup(cpi);
Vishesh734eff92020-06-20 21:46:36 +05303111 } else if (q_cfg->aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003112 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003113 }
David Turner2f3b5df2019-01-02 14:30:50 +00003114
Rostislav Pehlivanov3a964622018-03-14 18:00:32 +00003115 if (cm->seg.enabled) {
David Barkercab37552018-03-21 11:56:24 +00003116 if (!cm->seg.update_data && cm->prev_frame) {
Rostislav Pehlivanov3a964622018-03-14 18:00:32 +00003117 segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
Jerome Jiangb23571d2019-10-23 14:15:55 -07003118 cm->seg.enabled = cm->prev_frame->seg.enabled;
David Barker11c93562018-06-05 12:00:07 +01003119 } else {
Yaowu Xu7e450882019-04-30 15:09:18 -07003120 av1_calculate_segdata(&cm->seg);
Yue Chend90d3432018-03-16 11:28:42 -07003121 }
David Barkercab37552018-03-21 11:56:24 +00003122 } else {
3123 memset(&cm->seg, 0, sizeof(cm->seg));
Rostislav Pehlivanov3a964622018-03-14 18:00:32 +00003124 }
David Barkercab37552018-03-21 11:56:24 +00003125 segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
Jerome Jiangb23571d2019-10-23 14:15:55 -07003126 cm->cur_frame->seg.enabled = cm->seg.enabled;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003127
Yunqing Wangd1f32e62019-02-20 10:37:51 -08003128#if CONFIG_COLLECT_COMPONENT_TIMING
3129 start_timing(cpi, av1_encode_frame_time);
3130#endif
chiyotsai8b7cef82020-01-21 16:52:54 -08003131 // Set the motion vector precision based on mv stats from the last coded
3132 // frame.
3133 if (!frame_is_intra_only(cm)) {
3134 av1_pick_and_set_high_precision_mv(cpi, q);
3135
3136 // If the precision has changed during different iteration of the loop,
3137 // then we need to reset the global motion vectors
Urvang Joshib6409e92020-03-23 11:23:27 -07003138 if (loop_count > 0 &&
3139 cm->features.allow_high_precision_mv != last_loop_allow_hp) {
Vishesh8ba8bfe2020-04-03 14:20:29 +05303140 gm_info->search_done = 0;
chiyotsai8b7cef82020-01-21 16:52:54 -08003141 }
Urvang Joshib6409e92020-03-23 11:23:27 -07003142 last_loop_allow_hp = cm->features.allow_high_precision_mv;
chiyotsai8b7cef82020-01-21 16:52:54 -08003143 }
chiyotsaic666b1f2019-12-20 10:44:58 -08003144
Yaowu Xuc27fc142016-08-22 16:08:15 -07003145 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07003146 av1_encode_frame(cpi);
Marco Paniconic6cd72e2020-05-08 11:00:50 -07003147
chiyotsai51bd6482019-12-20 10:49:34 -08003148 // Reset the mv_stats in case we are interrupted by an intraframe or an
3149 // overlay frame.
3150 if (cpi->mv_stats.valid) {
3151 av1_zero(cpi->mv_stats);
3152 }
3153 // Gather the mv_stats for the next frame
3154 if (cpi->sf.hl_sf.high_precision_mv_usage == LAST_MV_DATA &&
3155 av1_frame_allows_smart_mv(cpi)) {
3156 av1_collect_mv_stats(cpi, q);
3157 }
chiyotsai51bd6482019-12-20 10:49:34 -08003158
Yunqing Wangd1f32e62019-02-20 10:37:51 -08003159#if CONFIG_COLLECT_COMPONENT_TIMING
3160 end_timing(cpi, av1_encode_frame_time);
3161#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003162
Yaowu Xuf883b422016-08-30 14:01:10 -07003163 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003164
3165 // Dummy pack of the bitstream using up to date stats to get an
3166 // accurate estimate of output frame size to determine if we need
3167 // to recode.
chiyotsai6b430132019-12-18 10:33:51 -08003168 const int do_dummy_pack =
3169 (cpi->sf.hl_sf.recode_loop >= ALLOW_RECODE_KFARFGF &&
Vishesh734eff92020-06-20 21:46:36 +05303170 oxcf->rc_cfg.mode != AOM_Q) ||
3171 oxcf->rc_cfg.min_cr > 0;
Hui Sua1d71842019-07-31 12:02:24 -07003172 if (do_dummy_pack) {
David Turner996b2c12018-12-07 15:52:30 +00003173 finalize_encoded_frame(cpi);
David Turner35cba132018-12-10 15:48:15 +00003174 int largest_tile_id = 0; // Output from bitstream: unused here
chiyotsaic666b1f2019-12-20 10:44:58 -08003175 if (av1_pack_bitstream(cpi, dest, size, &largest_tile_id) !=
3176 AOM_CODEC_OK) {
Tom Finegane4099e32018-01-23 12:01:51 -08003177 return AOM_CODEC_ERROR;
chiyotsaic666b1f2019-12-20 10:44:58 -08003178 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003179
3180 rc->projected_frame_size = (int)(*size) << 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003181 }
3182
Hui Suef139e12019-05-20 15:51:22 -07003183 if (allow_recode) {
David Turner2f3b5df2019-01-02 14:30:50 +00003184 // Update q and decide whether to do a recode loop
3185 recode_loop_update_q(cpi, &loop, &q, &q_low, &q_high, top_index,
3186 bottom_index, &undershoot_seen, &overshoot_seen,
Hui Suef139e12019-05-20 15:51:22 -07003187 &low_cr_seen, loop_at_this_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003188 }
3189
3190 // Special case for overlay frame.
Hui Su7e3eeaa2019-09-11 15:50:41 -07003191 if (loop && rc->is_src_frame_alt_ref &&
3192 rc->projected_frame_size < rc->max_frame_bandwidth) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003193 loop = 0;
Hui Su7e3eeaa2019-09-11 15:50:41 -07003194 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003195
chiyotsai76cd2652019-12-18 10:26:36 -08003196 if (allow_recode && !cpi->sf.gm_sf.gm_disable_recode &&
Vishesh8ba8bfe2020-04-03 14:20:29 +05303197 recode_loop_test_global_motion(cm->global_motion,
3198 cpi->td.rd_counts.global_motion_used,
3199 gm_info->params_cost)) {
David Turner2f3b5df2019-01-02 14:30:50 +00003200 loop = 1;
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003201 }
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003202
Yaowu Xuc27fc142016-08-22 16:08:15 -07003203 if (loop) {
3204 ++loop_count;
3205 ++loop_at_this_size;
3206
3207#if CONFIG_INTERNAL_STATS
3208 ++cpi->tot_recode_hits;
3209#endif
3210 }
Yunqing Wangd1f32e62019-02-20 10:37:51 -08003211#if CONFIG_COLLECT_COMPONENT_TIMING
3212 if (loop) printf("\n Recoding:");
3213#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003214 } while (loop);
Tom Finegane4099e32018-01-23 12:01:51 -08003215
3216 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003217}
Marco Paniconic6cd72e2020-05-08 11:00:50 -07003218#endif // !CONFIG_REALTIME_ONLY
Yaowu Xuc27fc142016-08-22 16:08:15 -07003219
Yue Chen2d8405c2020-06-10 14:42:05 -07003220/*!\brief Recode loop or a single loop for encoding one frame, followed by
3221 * in-loop deblocking filters, CDEF filters, and restoration filters.
3222 *
3223 * \ingroup high_level_algo
3224 * \callgraph
3225 * \callergraph
3226 *
3227 * \param[in] cpi Top-level encoder structure
3228 * \param[in] size Bitstream size
3229 * \param[in] dest Bitstream output
3230 * \param[in] sse Total distortion of the frame
3231 * \param[in] rate Total rate of the frame
3232 * \param[in] largest_tile_id Tile id of the last tile
3233 *
3234 * \return Returns a value to indicate if the encoding is done successfully.
3235 * \retval #AOM_CODEC_OK
3236 * \retval #AOM_CODEC_ERROR
3237 */
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003238static int encode_with_recode_loop_and_filter(AV1_COMP *cpi, size_t *size,
3239 uint8_t *dest, int64_t *sse,
3240 int64_t *rate,
3241 int *largest_tile_id) {
3242#if CONFIG_COLLECT_COMPONENT_TIMING
3243 start_timing(cpi, encode_with_recode_loop_time);
3244#endif
Marco Paniconic6cd72e2020-05-08 11:00:50 -07003245 int err;
3246#if CONFIG_REALTIME_ONLY
3247 err = encode_without_recode(cpi);
3248#else
Marco Paniconie635eb62020-05-14 14:01:02 -07003249 if (cpi->sf.hl_sf.recode_loop == DISALLOW_RECODE &&
3250 cpi->oxcf.mode == REALTIME)
Marco Paniconic6cd72e2020-05-08 11:00:50 -07003251 err = encode_without_recode(cpi);
3252 else
3253 err = encode_with_recode_loop(cpi, size, dest);
3254#endif
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003255#if CONFIG_COLLECT_COMPONENT_TIMING
3256 end_timing(cpi, encode_with_recode_loop_time);
3257#endif
3258 if (err != AOM_CODEC_OK) {
3259 if (err == -1) {
3260 // special case as described in encode_with_recode_loop().
3261 // Encoding was skipped.
3262 err = AOM_CODEC_OK;
3263 if (sse != NULL) *sse = INT64_MAX;
3264 if (rate != NULL) *rate = INT64_MAX;
3265 *largest_tile_id = 0;
3266 }
3267 return err;
3268 }
3269
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003270 AV1_COMMON *const cm = &cpi->common;
3271 SequenceHeader *const seq_params = &cm->seq_params;
3272
3273 // Special case code to reduce pulsing when key frames are forced at a
3274 // fixed interval. Note the reconstruction error if it is the frame before
3275 // the force key frame
3276 if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
Jerome Jiangfa1d1732019-08-06 10:31:20 -07003277#if CONFIG_AV1_HIGHBITDEPTH
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003278 if (seq_params->use_highbitdepth) {
3279 cpi->ambient_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
3280 } else {
3281 cpi->ambient_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
3282 }
Jerome Jiangfa1d1732019-08-06 10:31:20 -07003283#else
3284 cpi->ambient_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
3285#endif
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003286 }
3287
3288 cm->cur_frame->buf.color_primaries = seq_params->color_primaries;
3289 cm->cur_frame->buf.transfer_characteristics =
3290 seq_params->transfer_characteristics;
3291 cm->cur_frame->buf.matrix_coefficients = seq_params->matrix_coefficients;
3292 cm->cur_frame->buf.monochrome = seq_params->monochrome;
3293 cm->cur_frame->buf.chroma_sample_position =
3294 seq_params->chroma_sample_position;
3295 cm->cur_frame->buf.color_range = seq_params->color_range;
3296 cm->cur_frame->buf.render_width = cm->render_width;
3297 cm->cur_frame->buf.render_height = cm->render_height;
3298
3299 // TODO(zoeliu): For non-ref frames, loop filtering may need to be turned
3300 // off.
3301
3302 // Pick the loop filter level for the frame.
Urvang Joshib6409e92020-03-23 11:23:27 -07003303 if (!cm->features.allow_intrabc) {
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003304 loopfilter_frame(cpi, cm);
3305 } else {
3306 cm->lf.filter_level[0] = 0;
3307 cm->lf.filter_level[1] = 0;
3308 cm->cdef_info.cdef_bits = 0;
3309 cm->cdef_info.cdef_strengths[0] = 0;
3310 cm->cdef_info.nb_cdef_strengths = 1;
3311 cm->cdef_info.cdef_uv_strengths[0] = 0;
3312 cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
3313 cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
3314 cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
3315 }
3316
3317 // TODO(debargha): Fix mv search range on encoder side
3318 // aom_extend_frame_inner_borders(&cm->cur_frame->buf, av1_num_planes(cm));
3319 aom_extend_frame_borders(&cm->cur_frame->buf, av1_num_planes(cm));
3320
3321#ifdef OUTPUT_YUV_REC
3322 aom_write_one_yuv_frame(cm, &cm->cur_frame->buf);
3323#endif
3324
3325 finalize_encoded_frame(cpi);
3326 // Build the bitstream
3327#if CONFIG_COLLECT_COMPONENT_TIMING
3328 start_timing(cpi, av1_pack_bitstream_final_time);
3329#endif
3330 if (av1_pack_bitstream(cpi, dest, size, largest_tile_id) != AOM_CODEC_OK)
3331 return AOM_CODEC_ERROR;
3332#if CONFIG_COLLECT_COMPONENT_TIMING
3333 end_timing(cpi, av1_pack_bitstream_final_time);
3334#endif
3335
3336 // Compute sse and rate.
3337 if (sse != NULL) {
Jerome Jiangfa1d1732019-08-06 10:31:20 -07003338#if CONFIG_AV1_HIGHBITDEPTH
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003339 *sse = (seq_params->use_highbitdepth)
3340 ? aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf)
3341 : aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
Jerome Jiangfa1d1732019-08-06 10:31:20 -07003342#else
3343 *sse = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
3344#endif
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003345 }
3346 if (rate != NULL) {
3347 const int64_t bits = (*size << 3);
3348 *rate = (bits << 5); // To match scale.
3349 }
3350 return AOM_CODEC_OK;
3351}
3352
3353#if CONFIG_SUPERRES_IN_RECODE
3354
3355static void save_cur_buf(AV1_COMP *cpi) {
3356 CODING_CONTEXT *const cc = &cpi->coding_context;
3357 AV1_COMMON *cm = &cpi->common;
3358 const YV12_BUFFER_CONFIG *ybf = &cm->cur_frame->buf;
3359 memset(&cc->copy_buffer, 0, sizeof(cc->copy_buffer));
3360 if (aom_alloc_frame_buffer(&cc->copy_buffer, ybf->y_crop_width,
3361 ybf->y_crop_height, ybf->subsampling_x,
3362 ybf->subsampling_y,
3363 ybf->flags & YV12_FLAG_HIGHBITDEPTH, ybf->border,
Urvang Joshi6237b882020-03-26 15:02:26 -07003364 cm->features.byte_alignment) != AOM_CODEC_OK) {
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003365 aom_internal_error(
3366 &cm->error, AOM_CODEC_MEM_ERROR,
3367 "Failed to allocate copy buffer for saving coding context");
3368 }
3369 aom_yv12_copy_frame(ybf, &cc->copy_buffer, av1_num_planes(cm));
3370}
3371
3372// Coding context that only needs to be saved when recode loop includes
3373// filtering (deblocking, CDEF, superres post-encode upscale and/or loop
3374// restoraton).
3375static void save_extra_coding_context(AV1_COMP *cpi) {
3376 CODING_CONTEXT *const cc = &cpi->coding_context;
3377 AV1_COMMON *cm = &cpi->common;
3378
3379 cc->lf = cm->lf;
3380 cc->cdef_info = cm->cdef_info;
3381 cc->rc = cpi->rc;
3382}
3383
3384static void save_all_coding_context(AV1_COMP *cpi) {
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003385 save_cur_buf(cpi);
3386 save_extra_coding_context(cpi);
3387 if (!frame_is_intra_only(&cpi->common)) release_scaled_references(cpi);
3388}
3389
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003390static void restore_all_coding_context(AV1_COMP *cpi) {
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003391 restore_cur_buf(cpi);
3392 restore_extra_coding_context(cpi);
3393 if (!frame_is_intra_only(&cpi->common)) release_scaled_references(cpi);
3394}
3395
3396static int encode_with_and_without_superres(AV1_COMP *cpi, size_t *size,
3397 uint8_t *dest,
3398 int *largest_tile_id) {
3399 const AV1_COMMON *const cm = &cpi->common;
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003400 assert(cm->seq_params.enable_superres);
Satish Kumar Suman7a5f5f42020-06-09 14:20:47 +05303401 assert(av1_superres_in_recode_allowed(cpi));
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003402 aom_codec_err_t err = AOM_CODEC_OK;
3403 save_all_coding_context(cpi);
3404
3405 // Encode with superres.
Urvang Joshibc82d382019-11-01 17:59:20 -07003406#if SUPERRES_RECODE_ALL_RATIOS
Vishesh0d279aa2020-06-03 15:56:56 +05303407 SuperResCfg *const superres_cfg = &cpi->oxcf.superres_cfg;
Urvang Joshibc82d382019-11-01 17:59:20 -07003408 int64_t superres_sses[SCALE_NUMERATOR];
3409 int64_t superres_rates[SCALE_NUMERATOR];
3410 int superres_largest_tile_ids[SCALE_NUMERATOR];
3411 // Use superres for Key-frames and Alt-ref frames only.
3412 const GF_GROUP *const gf_group = &cpi->gf_group;
3413 if (gf_group->update_type[gf_group->index] != OVERLAY_UPDATE &&
3414 gf_group->update_type[gf_group->index] != INTNL_OVERLAY_UPDATE) {
3415 for (int denom = SCALE_NUMERATOR + 1; denom <= 2 * SCALE_NUMERATOR;
3416 ++denom) {
Vishesh0d279aa2020-06-03 15:56:56 +05303417 superres_cfg->superres_scale_denominator = denom;
3418 superres_cfg->superres_kf_scale_denominator = denom;
Urvang Joshibc82d382019-11-01 17:59:20 -07003419 const int this_index = denom - (SCALE_NUMERATOR + 1);
3420 err = encode_with_recode_loop_and_filter(
3421 cpi, size, dest, &superres_sses[this_index],
3422 &superres_rates[this_index], &superres_largest_tile_ids[this_index]);
3423 if (err != AOM_CODEC_OK) return err;
3424 restore_all_coding_context(cpi);
3425 }
3426 // Reset.
Vishesh0d279aa2020-06-03 15:56:56 +05303427 superres_cfg->superres_scale_denominator = SCALE_NUMERATOR;
3428 superres_cfg->superres_kf_scale_denominator = SCALE_NUMERATOR;
Urvang Joshibc82d382019-11-01 17:59:20 -07003429 } else {
3430 for (int denom = SCALE_NUMERATOR + 1; denom <= 2 * SCALE_NUMERATOR;
3431 ++denom) {
3432 const int this_index = denom - (SCALE_NUMERATOR + 1);
3433 superres_sses[this_index] = INT64_MAX;
3434 superres_rates[this_index] = INT64_MAX;
3435 }
3436 }
3437#else
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003438 int64_t sse1 = INT64_MAX;
3439 int64_t rate1 = INT64_MAX;
3440 int largest_tile_id1;
3441 err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse1, &rate1,
3442 &largest_tile_id1);
3443 if (err != AOM_CODEC_OK) return err;
Urvang Joshibc82d382019-11-01 17:59:20 -07003444 restore_all_coding_context(cpi);
3445#endif // SUPERRES_RECODE_ALL_RATIOS
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003446
3447 // Encode without superres.
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003448 int64_t sse2 = INT64_MAX;
3449 int64_t rate2 = INT64_MAX;
3450 int largest_tile_id2;
Urvang Joshi9d2606c2020-04-14 15:58:01 -07003451 cpi->superres_mode = AOM_SUPERRES_NONE; // To force full-res.
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003452 err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse2, &rate2,
3453 &largest_tile_id2);
Vishesh0d279aa2020-06-03 15:56:56 +05303454 cpi->superres_mode = cpi->oxcf.superres_cfg.superres_mode; // Reset.
3455 assert(cpi->oxcf.superres_cfg.superres_mode == AOM_SUPERRES_AUTO);
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003456 if (err != AOM_CODEC_OK) return err;
3457
3458 // Note: Both use common rdmult based on base qindex of fullres.
3459 const int64_t rdmult =
Urvang Joshi17814622020-03-27 17:26:17 -07003460 av1_compute_rd_mult_based_on_qindex(cpi, cm->quant_params.base_qindex);
Urvang Joshibc82d382019-11-01 17:59:20 -07003461
3462#if SUPERRES_RECODE_ALL_RATIOS
3463 // Find the best rdcost among all superres denoms.
3464 double proj_rdcost1 = DBL_MAX;
3465 int64_t sse1 = INT64_MAX;
3466 int64_t rate1 = INT64_MAX;
3467 int largest_tile_id1 = 0;
3468 (void)sse1;
3469 (void)rate1;
3470 (void)largest_tile_id1;
3471 int best_denom = -1;
3472 for (int denom = SCALE_NUMERATOR + 1; denom <= 2 * SCALE_NUMERATOR; ++denom) {
3473 const int this_index = denom - (SCALE_NUMERATOR + 1);
3474 const int64_t this_sse = superres_sses[this_index];
3475 const int64_t this_rate = superres_rates[this_index];
3476 const int this_largest_tile_id = superres_largest_tile_ids[this_index];
3477 const double this_rdcost = RDCOST_DBL(rdmult, this_rate, this_sse);
3478 if (this_rdcost < proj_rdcost1) {
3479 sse1 = this_sse;
3480 rate1 = this_rate;
3481 largest_tile_id1 = this_largest_tile_id;
3482 proj_rdcost1 = this_rdcost;
3483 best_denom = denom;
3484 }
3485 }
3486#else
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003487 const double proj_rdcost1 = RDCOST_DBL(rdmult, rate1, sse1);
Urvang Joshibc82d382019-11-01 17:59:20 -07003488#endif // SUPERRES_RECODE_ALL_RATIOS
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003489 const double proj_rdcost2 = RDCOST_DBL(rdmult, rate2, sse2);
3490
3491 // Re-encode with superres if it's better.
3492 if (proj_rdcost1 < proj_rdcost2) {
3493 restore_all_coding_context(cpi);
3494 // TODO(urvang): We should avoid rerunning the recode loop by saving
3495 // previous output+state, or running encode only for the selected 'q' in
3496 // previous step.
Urvang Joshibc82d382019-11-01 17:59:20 -07003497#if SUPERRES_RECODE_ALL_RATIOS
3498 // Again, temporarily force the best denom.
Vishesh0d279aa2020-06-03 15:56:56 +05303499 superres_cfg->superres_scale_denominator = best_denom;
3500 superres_cfg->superres_kf_scale_denominator = best_denom;
Urvang Joshibc82d382019-11-01 17:59:20 -07003501#endif // SUPERRES_RECODE_ALL_RATIOS
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003502 int64_t sse3 = INT64_MAX;
3503 int64_t rate3 = INT64_MAX;
3504 err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse3, &rate3,
3505 largest_tile_id);
3506 assert(sse1 == sse3);
3507 assert(rate1 == rate3);
3508 assert(largest_tile_id1 == *largest_tile_id);
Urvang Joshibc82d382019-11-01 17:59:20 -07003509#if SUPERRES_RECODE_ALL_RATIOS
3510 // Reset.
Vishesh0d279aa2020-06-03 15:56:56 +05303511 superres_cfg->superres_scale_denominator = SCALE_NUMERATOR;
3512 superres_cfg->superres_kf_scale_denominator = SCALE_NUMERATOR;
Urvang Joshibc82d382019-11-01 17:59:20 -07003513#endif // SUPERRES_RECODE_ALL_RATIOS
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003514 } else {
3515 *largest_tile_id = largest_tile_id2;
3516 }
3517
Urvang Joshibd6abad2020-04-08 01:00:18 -07003518 release_copy_buffer(&cpi->coding_context);
3519
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07003520 return err;
3521}
3522#endif // CONFIG_SUPERRES_IN_RECODE
3523
Yaowu Xuc27fc142016-08-22 16:08:15 -07003524#define DUMP_RECON_FRAMES 0
3525
3526#if DUMP_RECON_FRAMES == 1
3527// NOTE(zoeliu): For debug - Output the filtered reconstructed video.
Yaowu Xuf883b422016-08-30 14:01:10 -07003528static void dump_filtered_recon_frames(AV1_COMP *cpi) {
3529 AV1_COMMON *const cm = &cpi->common;
David Turnerd2a592e2018-11-16 14:59:31 +00003530 const CurrentFrame *const current_frame = &cm->current_frame;
David Turnerc29e1a92018-12-06 14:10:14 +00003531 const YV12_BUFFER_CONFIG *recon_buf = &cm->cur_frame->buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003532
Zoe Liub4f31032017-11-03 23:48:35 -07003533 if (recon_buf == NULL) {
David Turnerd2a592e2018-11-16 14:59:31 +00003534 printf("Frame %d is not ready.\n", current_frame->frame_number);
Zoe Liub4f31032017-11-03 23:48:35 -07003535 return;
3536 }
3537
Zoe Liu27deb382018-03-27 15:13:56 -07003538 static const int flag_list[REF_FRAMES] = { 0,
3539 AOM_LAST_FLAG,
3540 AOM_LAST2_FLAG,
3541 AOM_LAST3_FLAG,
3542 AOM_GOLD_FLAG,
3543 AOM_BWD_FLAG,
3544 AOM_ALT2_FLAG,
3545 AOM_ALT_FLAG };
Zoe Liub4f31032017-11-03 23:48:35 -07003546 printf(
3547 "\n***Frame=%d (frame_offset=%d, show_frame=%d, "
3548 "show_existing_frame=%d) "
3549 "[LAST LAST2 LAST3 GOLDEN BWD ALT2 ALT]=[",
David Turnerd2a592e2018-11-16 14:59:31 +00003550 current_frame->frame_number, current_frame->order_hint, cm->show_frame,
Zoe Liub4f31032017-11-03 23:48:35 -07003551 cm->show_existing_frame);
3552 for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
David Turnera21966b2018-12-05 14:48:49 +00003553 const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
3554 const int ref_offset = buf != NULL ? (int)buf->order_hint : -1;
Urvang Joshib6f17672019-03-05 11:51:02 -08003555 printf(" %d(%c)", ref_offset,
3556 (cpi->ref_frame_flags & flag_list[ref_frame]) ? 'Y' : 'N');
Zoe Liub4f31032017-11-03 23:48:35 -07003557 }
3558 printf(" ]\n");
Zoe Liub4f31032017-11-03 23:48:35 -07003559
3560 if (!cm->show_frame) {
3561 printf("Frame %d is a no show frame, so no image dump.\n",
David Turnerd2a592e2018-11-16 14:59:31 +00003562 current_frame->frame_number);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003563 return;
3564 }
3565
Zoe Liub4f31032017-11-03 23:48:35 -07003566 int h;
3567 char file_name[256] = "/tmp/enc_filtered_recon.yuv";
3568 FILE *f_recon = NULL;
3569
David Turnerd2a592e2018-11-16 14:59:31 +00003570 if (current_frame->frame_number == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003571 if ((f_recon = fopen(file_name, "wb")) == NULL) {
3572 printf("Unable to open file %s to write.\n", file_name);
3573 return;
3574 }
3575 } else {
3576 if ((f_recon = fopen(file_name, "ab")) == NULL) {
3577 printf("Unable to open file %s to append.\n", file_name);
3578 return;
3579 }
3580 }
3581 printf(
Zoe Liuf40a9572017-10-13 12:37:19 -07003582 "\nFrame=%5d, encode_update_type[%5d]=%1d, frame_offset=%d, "
3583 "show_frame=%d, show_existing_frame=%d, source_alt_ref_active=%d, "
Urvang Joshi7a890232019-03-22 17:00:31 -07003584 "refresh_alt_ref_frame=%d, "
Zoe Liuf40a9572017-10-13 12:37:19 -07003585 "y_stride=%4d, uv_stride=%4d, cm->width=%4d, cm->height=%4d\n\n",
Sarah Parkere1b22012019-06-06 16:35:25 -07003586 current_frame->frame_number, cpi->gf_group.index,
3587 cpi->gf_group.update_type[cpi->gf_group.index], current_frame->order_hint,
3588 cm->show_frame, cm->show_existing_frame, cpi->rc.source_alt_ref_active,
Jayasanker J24cb9bc2020-04-15 13:43:10 +05303589 cpi->refresh_frame.alt_ref_frame, recon_buf->y_stride,
3590 recon_buf->uv_stride, cm->width, cm->height);
Zoe Liue9b15e22017-07-19 15:53:01 -07003591#if 0
3592 int ref_frame;
3593 printf("get_ref_frame_map_idx: [");
3594 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame)
David Turnera21966b2018-12-05 14:48:49 +00003595 printf(" %d", get_ref_frame_map_idx(cm, ref_frame));
Zoe Liue9b15e22017-07-19 15:53:01 -07003596 printf(" ]\n");
Zoe Liue9b15e22017-07-19 15:53:01 -07003597#endif // 0
Yaowu Xuc27fc142016-08-22 16:08:15 -07003598
3599 // --- Y ---
3600 for (h = 0; h < cm->height; ++h) {
3601 fwrite(&recon_buf->y_buffer[h * recon_buf->y_stride], 1, cm->width,
3602 f_recon);
3603 }
3604 // --- U ---
3605 for (h = 0; h < (cm->height >> 1); ++h) {
3606 fwrite(&recon_buf->u_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
3607 f_recon);
3608 }
3609 // --- V ---
3610 for (h = 0; h < (cm->height >> 1); ++h) {
3611 fwrite(&recon_buf->v_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
3612 f_recon);
3613 }
3614
3615 fclose(f_recon);
3616}
3617#endif // DUMP_RECON_FRAMES
3618
Vishesh2260a592020-04-06 15:34:51 +05303619static int is_integer_mv(const YV12_BUFFER_CONFIG *cur_picture,
3620 const YV12_BUFFER_CONFIG *last_picture,
3621 ForceIntegerMVInfo *const force_intpel_info) {
David Turnerefed6372019-01-11 15:14:11 +00003622 aom_clear_system_state();
3623 // check use hash ME
3624 int k;
David Turnerefed6372019-01-11 15:14:11 +00003625
Ranjit Kumar Tulabandu9f26c992019-10-24 12:24:52 +05303626 const int block_size = FORCE_INT_MV_DECISION_BLOCK_SIZE;
David Turnerefed6372019-01-11 15:14:11 +00003627 const double threshold_current = 0.8;
3628 const double threshold_average = 0.95;
3629 const int max_history_size = 32;
3630 int T = 0; // total block
3631 int C = 0; // match with collocated block
3632 int S = 0; // smooth region but not match with collocated block
David Turnerefed6372019-01-11 15:14:11 +00003633
3634 const int pic_width = cur_picture->y_width;
3635 const int pic_height = cur_picture->y_height;
3636 for (int i = 0; i + block_size <= pic_height; i += block_size) {
3637 for (int j = 0; j + block_size <= pic_width; j += block_size) {
3638 const int x_pos = j;
3639 const int y_pos = i;
3640 int match = 1;
3641 T++;
3642
3643 // check whether collocated block match with current
3644 uint8_t *p_cur = cur_picture->y_buffer;
3645 uint8_t *p_ref = last_picture->y_buffer;
3646 int stride_cur = cur_picture->y_stride;
3647 int stride_ref = last_picture->y_stride;
3648 p_cur += (y_pos * stride_cur + x_pos);
3649 p_ref += (y_pos * stride_ref + x_pos);
3650
3651 if (cur_picture->flags & YV12_FLAG_HIGHBITDEPTH) {
3652 uint16_t *p16_cur = CONVERT_TO_SHORTPTR(p_cur);
3653 uint16_t *p16_ref = CONVERT_TO_SHORTPTR(p_ref);
3654 for (int tmpY = 0; tmpY < block_size && match; tmpY++) {
3655 for (int tmpX = 0; tmpX < block_size && match; tmpX++) {
3656 if (p16_cur[tmpX] != p16_ref[tmpX]) {
3657 match = 0;
3658 }
3659 }
3660 p16_cur += stride_cur;
3661 p16_ref += stride_ref;
3662 }
3663 } else {
3664 for (int tmpY = 0; tmpY < block_size && match; tmpY++) {
3665 for (int tmpX = 0; tmpX < block_size && match; tmpX++) {
3666 if (p_cur[tmpX] != p_ref[tmpX]) {
3667 match = 0;
3668 }
3669 }
3670 p_cur += stride_cur;
3671 p_ref += stride_ref;
3672 }
3673 }
3674
3675 if (match) {
3676 C++;
3677 continue;
3678 }
3679
3680 if (av1_hash_is_horizontal_perfect(cur_picture, block_size, x_pos,
3681 y_pos) ||
3682 av1_hash_is_vertical_perfect(cur_picture, block_size, x_pos, y_pos)) {
3683 S++;
3684 continue;
3685 }
David Turnerefed6372019-01-11 15:14:11 +00003686 }
3687 }
3688
3689 assert(T > 0);
Remya163db3c2020-02-17 14:29:41 +05303690 double cs_rate = ((double)(C + S)) / ((double)(T));
David Turnerefed6372019-01-11 15:14:11 +00003691
Vishesh2260a592020-04-06 15:34:51 +05303692 force_intpel_info->cs_rate_array[force_intpel_info->rate_index] = cs_rate;
David Turnerefed6372019-01-11 15:14:11 +00003693
Vishesh2260a592020-04-06 15:34:51 +05303694 force_intpel_info->rate_index =
3695 (force_intpel_info->rate_index + 1) % max_history_size;
3696 force_intpel_info->rate_size++;
3697 force_intpel_info->rate_size =
3698 AOMMIN(force_intpel_info->rate_size, max_history_size);
David Turnerefed6372019-01-11 15:14:11 +00003699
Remya163db3c2020-02-17 14:29:41 +05303700 if (cs_rate < threshold_current) {
David Turnerefed6372019-01-11 15:14:11 +00003701 return 0;
3702 }
3703
3704 if (C == T) {
3705 return 1;
3706 }
3707
Remya163db3c2020-02-17 14:29:41 +05303708 double cs_average = 0.0;
David Turnerefed6372019-01-11 15:14:11 +00003709
Vishesh2260a592020-04-06 15:34:51 +05303710 for (k = 0; k < force_intpel_info->rate_size; k++) {
3711 cs_average += force_intpel_info->cs_rate_array[k];
David Turnerefed6372019-01-11 15:14:11 +00003712 }
Vishesh2260a592020-04-06 15:34:51 +05303713 cs_average /= force_intpel_info->rate_size;
David Turnerefed6372019-01-11 15:14:11 +00003714
Remya163db3c2020-02-17 14:29:41 +05303715 if (cs_average < threshold_average) {
David Turnerefed6372019-01-11 15:14:11 +00003716 return 0;
3717 }
3718
Remya163db3c2020-02-17 14:29:41 +05303719 if ((T - C - S) < 0) {
David Turnerefed6372019-01-11 15:14:11 +00003720 return 1;
3721 }
3722
Remya163db3c2020-02-17 14:29:41 +05303723 if (cs_average > 1.01) {
David Turnerefed6372019-01-11 15:14:11 +00003724 return 1;
3725 }
3726
3727 return 0;
3728}
3729
David Turner73245762019-02-11 16:42:34 +00003730// Refresh reference frame buffers according to refresh_frame_flags.
3731static void refresh_reference_frames(AV1_COMP *cpi) {
3732 AV1_COMMON *const cm = &cpi->common;
3733 // All buffers are refreshed for shown keyframes and S-frames.
3734
3735 for (int ref_frame = 0; ref_frame < REF_FRAMES; ref_frame++) {
3736 if (((cm->current_frame.refresh_frame_flags >> ref_frame) & 1) == 1) {
3737 assign_frame_buffer_p(&cm->ref_frame_map[ref_frame], cm->cur_frame);
3738 }
3739 }
3740}
3741
sdengc23c7f12019-06-11 16:56:50 -07003742static void set_mb_ssim_rdmult_scaling(AV1_COMP *cpi) {
Urvang Joshi9dc909d2020-03-23 16:07:02 -07003743 const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
sdengc23c7f12019-06-11 16:56:50 -07003744 ThreadData *td = &cpi->td;
3745 MACROBLOCK *x = &td->mb;
3746 MACROBLOCKD *xd = &x->e_mbd;
3747 uint8_t *y_buffer = cpi->source->y_buffer;
3748 const int y_stride = cpi->source->y_stride;
3749 const int block_size = BLOCK_16X16;
3750
3751 const int num_mi_w = mi_size_wide[block_size];
3752 const int num_mi_h = mi_size_high[block_size];
Urvang Joshi9dc909d2020-03-23 16:07:02 -07003753 const int num_cols = (mi_params->mi_cols + num_mi_w - 1) / num_mi_w;
3754 const int num_rows = (mi_params->mi_rows + num_mi_h - 1) / num_mi_h;
sdengc23c7f12019-06-11 16:56:50 -07003755 double log_sum = 0.0;
sdengc23c7f12019-06-11 16:56:50 -07003756 const int use_hbd = cpi->source->flags & YV12_FLAG_HIGHBITDEPTH;
3757
sdengc23c7f12019-06-11 16:56:50 -07003758 // Loop through each 16x16 block.
Urvang Joshi9dc909d2020-03-23 16:07:02 -07003759 for (int row = 0; row < num_rows; ++row) {
3760 for (int col = 0; col < num_cols; ++col) {
sdengc23c7f12019-06-11 16:56:50 -07003761 double var = 0.0, num_of_var = 0.0;
3762 const int index = row * num_cols + col;
3763
3764 // Loop through each 8x8 block.
Urvang Joshi9dc909d2020-03-23 16:07:02 -07003765 for (int mi_row = row * num_mi_h;
3766 mi_row < mi_params->mi_rows && mi_row < (row + 1) * num_mi_h;
3767 mi_row += 2) {
3768 for (int mi_col = col * num_mi_w;
3769 mi_col < mi_params->mi_cols && mi_col < (col + 1) * num_mi_w;
sdengc23c7f12019-06-11 16:56:50 -07003770 mi_col += 2) {
3771 struct buf_2d buf;
3772 const int row_offset_y = mi_row << 2;
3773 const int col_offset_y = mi_col << 2;
3774
3775 buf.buf = y_buffer + row_offset_y * y_stride + col_offset_y;
3776 buf.stride = y_stride;
3777
3778 if (use_hbd) {
3779 var += av1_high_get_sby_perpixel_variance(cpi, &buf, BLOCK_8X8,
3780 xd->bd);
3781 } else {
3782 var += av1_get_sby_perpixel_variance(cpi, &buf, BLOCK_8X8);
3783 }
3784
3785 num_of_var += 1.0;
3786 }
3787 }
sdeng32185d12019-06-19 14:47:09 -07003788 var = var / num_of_var;
sdengbdc0cd22019-11-11 15:09:34 -08003789
3790 // Curve fitting with an exponential model on all 16x16 blocks from the
3791 // midres dataset.
3792 var = 67.035434 * (1 - exp(-0.0021489 * var)) + 17.492222;
sdengc23c7f12019-06-11 16:56:50 -07003793 cpi->ssim_rdmult_scaling_factors[index] = var;
3794 log_sum += log(var);
3795 }
3796 }
3797 log_sum = exp(log_sum / (double)(num_rows * num_cols));
3798
Urvang Joshi9dc909d2020-03-23 16:07:02 -07003799 for (int row = 0; row < num_rows; ++row) {
3800 for (int col = 0; col < num_cols; ++col) {
sdengc23c7f12019-06-11 16:56:50 -07003801 const int index = row * num_cols + col;
3802 cpi->ssim_rdmult_scaling_factors[index] /= log_sum;
3803 }
3804 }
sdengc23c7f12019-06-11 16:56:50 -07003805}
3806
Yunqing Wangd8fd9e72019-12-26 15:36:31 -08003807extern void av1_print_frame_contexts(const FRAME_CONTEXT *fc,
3808 const char *filename);
3809
Yue Chen2d8405c2020-06-10 14:42:05 -07003810/*!\brief Run the final pass encoding for 1-pass/2-pass encoding mode, and pack
3811 * the bitstream
3812 *
3813 * \ingroup high_level_algo
3814 * \callgraph
3815 * \callergraph
3816 *
3817 * \param[in] cpi Top-level encoder structure
3818 * \param[in] size Bitstream size
3819 * \param[in] dest Bitstream output
3820 *
3821 * \return Returns a value to indicate if the encoding is done successfully.
3822 * \retval #AOM_CODEC_OK
3823 * \retval #AOM_CODEC_ERROR
3824 */
David Turner73245762019-02-11 16:42:34 +00003825static int encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
3826 uint8_t *dest) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003827 AV1_COMMON *const cm = &cpi->common;
Urvang Joshi20cf30e2018-07-19 02:33:58 -07003828 SequenceHeader *const seq_params = &cm->seq_params;
David Turnerd2a592e2018-11-16 14:59:31 +00003829 CurrentFrame *const current_frame = &cm->current_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003830 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003831 struct segmentation *const seg = &cm->seg;
Urvang Joshib6409e92020-03-23 11:23:27 -07003832 FeatureFlags *const features = &cm->features;
Vishesh0481a782020-06-11 14:32:46 +05303833 const TileConfig *const tile_cfg = &oxcf->tile_cfg;
Thomas Davies4822e142017-10-10 11:30:36 +01003834
Yunqing Wangd1f32e62019-02-20 10:37:51 -08003835#if CONFIG_COLLECT_COMPONENT_TIMING
3836 start_timing(cpi, encode_frame_to_data_rate_time);
3837#endif
3838
chiyotsai8b8f8a22020-04-21 11:03:47 -07003839 if (frame_is_intra_only(cm)) {
3840 av1_set_screen_content_options(cpi, features);
3841 cpi->is_screen_content_type = features->allow_screen_content_tools;
3842 }
3843
Fangwen Fu8d164de2016-12-14 13:40:54 -08003844 // frame type has been decided outside of this function call
David Turnerd2a592e2018-11-16 14:59:31 +00003845 cm->cur_frame->frame_type = current_frame->frame_type;
Debargha Mukherjee07a7c1f2018-03-21 17:39:13 -07003846
Vishesh0481a782020-06-11 14:32:46 +05303847 cm->tiles.large_scale = tile_cfg->enable_large_scale_tile;
3848 cm->tiles.single_tile_decoding = tile_cfg->enable_single_tile_decoding;
Yunqing Wang9612d552018-05-15 14:58:30 -07003849
Urvang Joshib6409e92020-03-23 11:23:27 -07003850 features->allow_ref_frame_mvs &= frame_might_allow_ref_frame_mvs(cm);
3851 // features->allow_ref_frame_mvs needs to be written into the frame header
Urvang Joshi54ffae72020-03-23 13:37:10 -07003852 // while cm->tiles.large_scale is 1, therefore, "cm->tiles.large_scale=1" case
Urvang Joshib6409e92020-03-23 11:23:27 -07003853 // is separated from frame_might_allow_ref_frame_mvs().
Urvang Joshi54ffae72020-03-23 13:37:10 -07003854 features->allow_ref_frame_mvs &= !cm->tiles.large_scale;
Yunqing Wangd48fb162018-06-15 10:55:28 -07003855
Vishesh015b4962020-06-15 14:19:55 +05303856 features->allow_warped_motion = oxcf->motion_mode_cfg.allow_warped_motion &&
3857 frame_might_allow_warped_motion(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003858
Urvang Joshi1de67aa2020-03-20 11:21:57 -07003859 cpi->last_frame_type = current_frame->frame_type;
Sachin Kumar Gargfd39b232019-01-03 17:41:09 +05303860
Sarah Parker1a72a1c2020-04-24 15:49:47 -07003861 if (frame_is_sframe(cm)) {
3862 GF_GROUP *gf_group = &cpi->gf_group;
3863 RATE_CONTROL *const rc = &cpi->rc;
3864 // S frame will wipe out any previously encoded altref so we cannot place
3865 // an overlay frame
3866 gf_group->update_type[gf_group->size] = GF_UPDATE;
3867 rc->source_alt_ref_active = 0;
3868 }
3869
Sarah Parker33005522018-07-27 14:46:25 -07003870 if (encode_show_existing_frame(cm)) {
David Turner996b2c12018-12-07 15:52:30 +00003871 finalize_encoded_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003872 // Build the bitstream
David Turner35cba132018-12-10 15:48:15 +00003873 int largest_tile_id = 0; // Output from bitstream: unused here
3874 if (av1_pack_bitstream(cpi, dest, size, &largest_tile_id) != AOM_CODEC_OK)
Tom Finegane4099e32018-01-23 12:01:51 -08003875 return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003876
David Turner90311862018-11-29 13:34:36 +00003877 if (seq_params->frame_id_numbers_present_flag &&
3878 current_frame->frame_type == KEY_FRAME) {
3879 // Displaying a forward key-frame, so reset the ref buffer IDs
3880 int display_frame_id = cm->ref_frame_id[cpi->existing_fb_idx_to_show];
3881 for (int i = 0; i < REF_FRAMES; i++)
3882 cm->ref_frame_id[i] = display_frame_id;
3883 }
3884
Debargha Mukherjeef2e5bb32018-03-26 14:35:24 -07003885 cpi->seq_params_locked = 1;
3886
Yaowu Xuc27fc142016-08-22 16:08:15 -07003887#if DUMP_RECON_FRAMES == 1
3888 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
3889 dump_filtered_recon_frames(cpi);
3890#endif // DUMP_RECON_FRAMES
3891
David Turner73245762019-02-11 16:42:34 +00003892 // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
3893 // for the purpose to verify no mismatch between encoder and decoder.
3894 if (cm->show_frame) cpi->last_show_frame_buf = cm->cur_frame;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003895
David Turner73245762019-02-11 16:42:34 +00003896 refresh_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003897
Yaowu Xuc27fc142016-08-22 16:08:15 -07003898 // Since we allocate a spot for the OVERLAY frame in the gf group, we need
3899 // to do post-encoding update accordingly.
3900 if (cpi->rc.is_src_frame_alt_ref) {
Debargha Mukherjee7166f222017-09-05 21:32:42 -07003901 av1_set_target_rate(cpi, cm->width, cm->height);
Yaowu Xuf883b422016-08-30 14:01:10 -07003902 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003904
Mufaddal Chakeraea4c6d52020-06-12 15:09:14 +05303905 if (is_psnr_calc_enabled(cpi)) {
3906 cpi->source =
3907 realloc_and_scale_source(cpi, cm->cur_frame->buf.y_crop_width,
3908 cm->cur_frame->buf.y_crop_height);
3909 }
David Turnerd2a592e2018-11-16 14:59:31 +00003910 ++current_frame->frame_number;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003911
Tom Finegane4099e32018-01-23 12:01:51 -08003912 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003913 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003914
David Turnerefed6372019-01-11 15:14:11 +00003915 // Work out whether to force_integer_mv this frame
Mufaddal Chakerae7326122019-12-04 14:49:09 +05303916 if (!is_stat_generation_stage(cpi) &&
Urvang Joshib6409e92020-03-23 11:23:27 -07003917 cpi->common.features.allow_screen_content_tools &&
3918 !frame_is_intra_only(cm)) {
David Turnerefed6372019-01-11 15:14:11 +00003919 if (cpi->common.seq_params.force_integer_mv == 2) {
3920 // Adaptive mode: see what previous frame encoded did
3921 if (cpi->unscaled_last_source != NULL) {
Vishesh2260a592020-04-06 15:34:51 +05303922 features->cur_frame_force_integer_mv = is_integer_mv(
3923 cpi->source, cpi->unscaled_last_source, &cpi->force_intpel_info);
David Turnerefed6372019-01-11 15:14:11 +00003924 } else {
Urvang Joshib6409e92020-03-23 11:23:27 -07003925 cpi->common.features.cur_frame_force_integer_mv = 0;
David Turnerefed6372019-01-11 15:14:11 +00003926 }
3927 } else {
Urvang Joshib6409e92020-03-23 11:23:27 -07003928 cpi->common.features.cur_frame_force_integer_mv =
David Turnerefed6372019-01-11 15:14:11 +00003929 cpi->common.seq_params.force_integer_mv;
3930 }
3931 } else {
Urvang Joshib6409e92020-03-23 11:23:27 -07003932 cpi->common.features.cur_frame_force_integer_mv = 0;
David Turnerefed6372019-01-11 15:14:11 +00003933 }
3934
Yaowu Xuc27fc142016-08-22 16:08:15 -07003935 // Set default state for segment based loop filter update flags.
3936 cm->lf.mode_ref_delta_update = 0;
3937
Yaowu Xuc27fc142016-08-22 16:08:15 -07003938 // Set various flags etc to special state if it is a key frame.
Tarek AMARAc9813852018-03-05 18:40:18 -05003939 if (frame_is_intra_only(cm) || frame_is_sframe(cm)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003940 // Reset the loop filter deltas and segmentation map.
Yaowu Xuf883b422016-08-30 14:01:10 -07003941 av1_reset_segment_features(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942
3943 // If segmentation is enabled force a map update for key frames.
3944 if (seg->enabled) {
3945 seg->update_map = 1;
3946 seg->update_data = 1;
3947 }
3948
3949 // The alternate reference frame cannot be active for a key frame.
3950 cpi->rc.source_alt_ref_active = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951 }
Vishesh0481a782020-06-11 14:32:46 +05303952 if (tile_cfg->mtu == 0) {
3953 cpi->num_tg = tile_cfg->num_tile_groups;
Thomas Daviesaf6df172016-11-09 14:04:18 +00003954 } else {
Yaowu Xu859a5272016-11-10 15:32:21 -08003955 // Use a default value for the purposes of weighting costs in probability
3956 // updates
Urvang Joshi1de67aa2020-03-20 11:21:57 -07003957 cpi->num_tg = DEFAULT_MAX_NUM_TG;
Thomas Daviesaf6df172016-11-09 14:04:18 +00003958 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003959
3960 // For 1 pass CBR, check if we are dropping this frame.
3961 // Never drop on key frame.
Vishesh39e74092020-06-16 17:13:48 +05303962 if (has_no_stats_stage(cpi) && oxcf->rc_cfg.mode == AOM_CBR &&
David Turnerd2a592e2018-11-16 14:59:31 +00003963 current_frame->frame_type != KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003964 if (av1_rc_drop_frame(cpi)) {
3965 av1_rc_postencode_update_drop_frame(cpi);
David Turnera4c96252019-01-11 16:36:39 +00003966 release_scaled_references(cpi);
Tom Finegane4099e32018-01-23 12:01:51 -08003967 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003968 }
3969 }
3970
sdengc23c7f12019-06-11 16:56:50 -07003971 if (oxcf->tuning == AOM_TUNE_SSIM) set_mb_ssim_rdmult_scaling(cpi);
3972
sdeng01959162019-12-20 10:46:24 -08003973#if CONFIG_TUNE_VMAF
3974 if (oxcf->tuning == AOM_TUNE_VMAF_WITHOUT_PREPROCESSING ||
sdeng615dc242020-02-04 16:06:14 -08003975 oxcf->tuning == AOM_TUNE_VMAF_MAX_GAIN) {
sdeng01959162019-12-20 10:46:24 -08003976 av1_set_mb_vmaf_rdmult_scaling(cpi);
sdeng29c62152019-12-09 12:44:18 -08003977 }
sdeng01959162019-12-20 10:46:24 -08003978#endif
sdeng29c62152019-12-09 12:44:18 -08003979
Yaowu Xuf883b422016-08-30 14:01:10 -07003980 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003981
3982#if CONFIG_INTERNAL_STATS
3983 memset(cpi->mode_chosen_counts, 0,
3984 MAX_MODES * sizeof(*cpi->mode_chosen_counts));
3985#endif
3986
Urvang Joshi20cf30e2018-07-19 02:33:58 -07003987 if (seq_params->frame_id_numbers_present_flag) {
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01003988 /* Non-normative definition of current_frame_id ("frame counter" with
Johann123e8a62017-12-28 14:40:49 -08003989 * wraparound) */
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01003990 if (cm->current_frame_id == -1) {
David Barker49a76562016-12-07 14:50:21 +00003991 int lsb, msb;
Yaowu Xud3e7c682017-12-21 14:08:25 -08003992 /* quasi-random initialization of current_frame_id for a key frame */
Alex Conversef77fd0b2017-04-20 11:00:24 -07003993 if (cpi->source->flags & YV12_FLAG_HIGHBITDEPTH) {
3994 lsb = CONVERT_TO_SHORTPTR(cpi->source->y_buffer)[0] & 0xff;
3995 msb = CONVERT_TO_SHORTPTR(cpi->source->y_buffer)[1] & 0xff;
David Barker49a76562016-12-07 14:50:21 +00003996 } else {
Alex Conversef77fd0b2017-04-20 11:00:24 -07003997 lsb = cpi->source->y_buffer[0] & 0xff;
3998 msb = cpi->source->y_buffer[1] & 0xff;
David Barker49a76562016-12-07 14:50:21 +00003999 }
David Turner760a2f42018-12-07 15:25:36 +00004000 cm->current_frame_id =
4001 ((msb << 8) + lsb) % (1 << seq_params->frame_id_length);
Tarek AMARAc9813852018-03-05 18:40:18 -05004002
4003 // S_frame is meant for stitching different streams of different
4004 // resolutions together, so current_frame_id must be the
4005 // same across different streams of the same content current_frame_id
4006 // should be the same and not random. 0x37 is a chosen number as start
4007 // point
Vishesh7e9873d2020-06-08 15:41:33 +05304008 if (oxcf->kf_cfg.sframe_dist != 0) cm->current_frame_id = 0x37;
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004009 } else {
4010 cm->current_frame_id =
David Turner760a2f42018-12-07 15:25:36 +00004011 (cm->current_frame_id + 1 + (1 << seq_params->frame_id_length)) %
4012 (1 << seq_params->frame_id_length);
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004013 }
4014 }
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004015
Vishesh7e9873d2020-06-08 15:41:33 +05304016 switch (oxcf->cdf_update_mode) {
Hui Su483a8452018-02-26 12:28:48 -08004017 case 0: // No CDF update for any frames(4~6% compression loss).
Urvang Joshib6409e92020-03-23 11:23:27 -07004018 features->disable_cdf_update = 1;
Hui Su483a8452018-02-26 12:28:48 -08004019 break;
4020 case 1: // Enable CDF update for all frames.
Urvang Joshib6409e92020-03-23 11:23:27 -07004021 features->disable_cdf_update = 0;
Hui Su483a8452018-02-26 12:28:48 -08004022 break;
4023 case 2:
4024 // Strategically determine at which frames to do CDF update.
4025 // Currently only enable CDF update for all-intra and no-show frames(1.5%
4026 // compression loss).
4027 // TODO(huisu@google.com): design schemes for various trade-offs between
4028 // compression quality and decoding speed.
Urvang Joshib6409e92020-03-23 11:23:27 -07004029 features->disable_cdf_update =
Hui Sub1b76b32018-02-27 15:24:48 -08004030 (frame_is_intra_only(cm) || !cm->show_frame) ? 0 : 1;
Hui Su483a8452018-02-26 12:28:48 -08004031 break;
4032 }
Urvang Joshi450a9a22020-03-31 16:00:22 -07004033 seq_params->timing_info_present &= !seq_params->reduced_still_picture_hdr;
Hui Su483a8452018-02-26 12:28:48 -08004034
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07004035 int largest_tile_id = 0;
4036#if CONFIG_SUPERRES_IN_RECODE
Satish Kumar Suman7a5f5f42020-06-09 14:20:47 +05304037 if (av1_superres_in_recode_allowed(cpi)) {
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07004038 if (encode_with_and_without_superres(cpi, size, dest, &largest_tile_id) !=
4039 AOM_CODEC_OK) {
4040 return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004041 }
Hui Su06463e42018-02-23 22:17:36 -08004042 } else {
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07004043#endif // CONFIG_SUPERRES_IN_RECODE
4044 if (encode_with_recode_loop_and_filter(cpi, size, dest, NULL, NULL,
4045 &largest_tile_id) != AOM_CODEC_OK) {
4046 return AOM_CODEC_ERROR;
4047 }
4048#if CONFIG_SUPERRES_IN_RECODE
Hui Su06463e42018-02-23 22:17:36 -08004049 }
Urvang Joshi0e8b6ed2019-06-20 15:36:21 -07004050#endif // CONFIG_SUPERRES_IN_RECODE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004051
Debargha Mukherjeef2e5bb32018-03-26 14:35:24 -07004052 cpi->seq_params_locked = 1;
4053
David Turner996b2c12018-12-07 15:52:30 +00004054 // Update reference frame ids for reference frames this frame will overwrite
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004055 if (seq_params->frame_id_numbers_present_flag) {
David Turner996b2c12018-12-07 15:52:30 +00004056 for (int i = 0; i < REF_FRAMES; i++) {
4057 if ((current_frame->refresh_frame_flags >> i) & 1) {
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004058 cm->ref_frame_id[i] = cm->current_frame_id;
4059 }
4060 }
4061 }
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004062
Yaowu Xuc27fc142016-08-22 16:08:15 -07004063#if DUMP_RECON_FRAMES == 1
4064 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
Zoe Liub4f31032017-11-03 23:48:35 -07004065 dump_filtered_recon_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004066#endif // DUMP_RECON_FRAMES
4067
Soo-Chul Han934af352017-10-15 15:21:51 -04004068 if (cm->seg.enabled) {
4069 if (cm->seg.update_map) {
4070 update_reference_segmentation_map(cpi);
Yue Chend90d3432018-03-16 11:28:42 -07004071 } else if (cm->last_frame_seg_map) {
David Turnerb757ce02018-11-12 15:01:28 +00004072 memcpy(cm->cur_frame->seg_map, cm->last_frame_seg_map,
Urvang Joshi9dc909d2020-03-23 16:07:02 -07004073 cm->mi_params.mi_cols * cm->mi_params.mi_rows * sizeof(uint8_t));
Soo-Chul Han934af352017-10-15 15:21:51 -04004074 }
4075 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004076
4077 if (frame_is_intra_only(cm) == 0) {
4078 release_scaled_references(cpi);
4079 }
4080
David Turner73245762019-02-11 16:42:34 +00004081 // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
4082 // for the purpose to verify no mismatch between encoder and decoder.
4083 if (cm->show_frame) cpi->last_show_frame_buf = cm->cur_frame;
4084
4085 refresh_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004086
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08004087#if CONFIG_ENTROPY_STATS
Yue Chencc6a6ef2018-05-21 16:21:05 -07004088 av1_accumulate_frame_counts(&aggregate_fc, &cpi->counts);
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08004089#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004090
Urvang Joshi6237b882020-03-26 15:02:26 -07004091 if (features->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
David Turner35cba132018-12-10 15:48:15 +00004092 *cm->fc = cpi->tile_data[largest_tile_id].tctx;
Hui Sudc54be62018-03-14 19:14:28 -07004093 av1_reset_cdf_symbol_counters(cm->fc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004094 }
Urvang Joshi54ffae72020-03-23 13:37:10 -07004095 if (!cm->tiles.large_scale) {
David Turnera4c96252019-01-11 16:36:39 +00004096 cm->cur_frame->frame_context = *cm->fc;
4097 }
Yunqing Wangd8fd9e72019-12-26 15:36:31 -08004098
Vishesh0481a782020-06-11 14:32:46 +05304099 if (tile_cfg->enable_ext_tile_debug) {
Yunqing Wangd8fd9e72019-12-26 15:36:31 -08004100 // (yunqing) This test ensures the correctness of large scale tile coding.
Urvang Joshi54ffae72020-03-23 13:37:10 -07004101 if (cm->tiles.large_scale && is_stat_consumption_stage(cpi)) {
Yunqing Wangd8fd9e72019-12-26 15:36:31 -08004102 char fn[20] = "./fc";
4103 fn[4] = current_frame->frame_number / 100 + '0';
4104 fn[5] = (current_frame->frame_number % 100) / 10 + '0';
4105 fn[6] = (current_frame->frame_number % 10) + '0';
4106 fn[7] = '\0';
4107 av1_print_frame_contexts(cm->fc, fn);
4108 }
David Turnera4c96252019-01-11 16:36:39 +00004109 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004110
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004111#if CONFIG_COLLECT_COMPONENT_TIMING
4112 end_timing(cpi, encode_frame_to_data_rate_time);
4113
4114 // Print out timing information.
4115 int i;
chiyotsai9c484b32019-03-07 16:01:50 -08004116 fprintf(stderr, "\n Frame number: %d, Frame type: %s, Show Frame: %d\n",
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004117 cm->current_frame.frame_number,
chiyotsai9c484b32019-03-07 16:01:50 -08004118 get_frame_type_enum(cm->current_frame.frame_type), cm->show_frame);
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004119 for (i = 0; i < kTimingComponents; i++) {
4120 cpi->component_time[i] += cpi->frame_component_time[i];
4121 fprintf(stderr, " %s: %" PRId64 " us (total: %" PRId64 " us)\n",
4122 get_component_name(i), cpi->frame_component_time[i],
4123 cpi->component_time[i]);
4124 cpi->frame_component_time[i] = 0;
4125 }
4126#endif
4127
Urvang Joshi1de67aa2020-03-20 11:21:57 -07004128 cpi->last_frame_type = current_frame->frame_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004129
Yaowu Xuf883b422016-08-30 14:01:10 -07004130 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004131
Yaowu Xuc27fc142016-08-22 16:08:15 -07004132 // Clear the one shot update flags for segmentation map and mode/ref loop
4133 // filter deltas.
4134 cm->seg.update_map = 0;
4135 cm->seg.update_data = 0;
4136 cm->lf.mode_ref_delta_update = 0;
4137
Wei-Ting Linfb7dc062018-06-28 18:26:13 -07004138 // A droppable frame might not be shown but it always
4139 // takes a space in the gf group. Therefore, even when
4140 // it is not shown, we still need update the count down.
4141
Yaowu Xuc27fc142016-08-22 16:08:15 -07004142 if (cm->show_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004143 // Don't increment frame counters if this was an altref buffer
4144 // update not a real frame
David Turnerd2a592e2018-11-16 14:59:31 +00004145 ++current_frame->frame_number;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004146 }
4147
Tom Finegane4099e32018-01-23 12:01:51 -08004148 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004149}
4150
David Turner056f7cd2019-01-07 17:48:13 +00004151int av1_encode(AV1_COMP *const cpi, uint8_t *const dest,
David Turnercb5e36f2019-01-17 17:15:25 +00004152 const EncodeFrameInput *const frame_input,
David Turner056f7cd2019-01-07 17:48:13 +00004153 const EncodeFrameParams *const frame_params,
4154 EncodeFrameResults *const frame_results) {
David Turner07dbd8e2019-01-08 17:16:25 +00004155 AV1_COMMON *const cm = &cpi->common;
David Turnera7f133c2019-01-22 14:47:16 +00004156 CurrentFrame *const current_frame = &cm->current_frame;
David Turner07dbd8e2019-01-08 17:16:25 +00004157
David Turnercb5e36f2019-01-17 17:15:25 +00004158 cpi->unscaled_source = frame_input->source;
4159 cpi->source = frame_input->source;
4160 cpi->unscaled_last_source = frame_input->last_source;
David Turner056f7cd2019-01-07 17:48:13 +00004161
David Turner6e8b4d92019-02-18 15:01:33 +00004162 current_frame->refresh_frame_flags = frame_params->refresh_frame_flags;
Urvang Joshib6409e92020-03-23 11:23:27 -07004163 cm->features.error_resilient_mode = frame_params->error_resilient_mode;
Urvang Joshi6237b882020-03-26 15:02:26 -07004164 cm->features.primary_ref_frame = frame_params->primary_ref_frame;
David Turner475a3132019-01-18 15:17:17 +00004165 cm->current_frame.frame_type = frame_params->frame_type;
David Turnerdedd8ff2019-01-23 13:59:46 +00004166 cm->show_frame = frame_params->show_frame;
David Turner07dbd8e2019-01-08 17:16:25 +00004167 cpi->ref_frame_flags = frame_params->ref_frame_flags;
David Turner04b70d82019-01-24 15:39:19 +00004168 cpi->speed = frame_params->speed;
David Turnere86ee0d2019-02-18 17:16:28 +00004169 cm->show_existing_frame = frame_params->show_existing_frame;
4170 cpi->existing_fb_idx_to_show = frame_params->existing_fb_idx_to_show;
David Turner07dbd8e2019-01-08 17:16:25 +00004171
David Turner73245762019-02-11 16:42:34 +00004172 memcpy(cm->remapped_ref_idx, frame_params->remapped_ref_idx,
4173 REF_FRAMES * sizeof(*cm->remapped_ref_idx));
4174
Jayasanker J24cb9bc2020-04-15 13:43:10 +05304175 memcpy(&cpi->refresh_frame, &frame_params->refresh_frame,
4176 sizeof(cpi->refresh_frame));
David Turnerfe3aecb2019-02-06 14:42:42 +00004177
David Turnera7f133c2019-01-22 14:47:16 +00004178 if (current_frame->frame_type == KEY_FRAME && cm->show_frame)
4179 current_frame->frame_number = 0;
4180
Remyafc038662020-02-06 11:46:11 +05304181 current_frame->order_hint =
4182 current_frame->frame_number + frame_params->order_offset;
4183 current_frame->display_order_hint = current_frame->order_hint;
4184 current_frame->order_hint %=
4185 (1 << (cm->seq_params.order_hint_info.order_hint_bits_minus_1 + 1));
David Turnera7f133c2019-01-22 14:47:16 +00004186
Mufaddal Chakerae7326122019-12-04 14:49:09 +05304187 if (is_stat_generation_stage(cpi)) {
Jerome Jiang2612b4d2019-05-29 17:46:47 -07004188#if !CONFIG_REALTIME_ONLY
David Turnercb5e36f2019-01-17 17:15:25 +00004189 av1_first_pass(cpi, frame_input->ts_duration);
Jerome Jiang2612b4d2019-05-29 17:46:47 -07004190#endif
David Turnercb5e36f2019-01-17 17:15:25 +00004191 } else if (cpi->oxcf.pass == 0 || cpi->oxcf.pass == 2) {
David Turner73245762019-02-11 16:42:34 +00004192 if (encode_frame_to_data_rate(cpi, &frame_results->size, dest) !=
4193 AOM_CODEC_OK) {
David Turnercb5e36f2019-01-17 17:15:25 +00004194 return AOM_CODEC_ERROR;
4195 }
4196 } else {
David Turner056f7cd2019-01-07 17:48:13 +00004197 return AOM_CODEC_ERROR;
4198 }
4199
4200 return AOM_CODEC_OK;
4201}
4202
Neil Birkbecka2893ab2018-06-08 14:45:13 -07004203#if CONFIG_DENOISE
4204static int apply_denoise_2d(AV1_COMP *cpi, YV12_BUFFER_CONFIG *sd,
4205 int block_size, float noise_level,
4206 int64_t time_stamp, int64_t end_time) {
4207 AV1_COMMON *const cm = &cpi->common;
4208 if (!cpi->denoise_and_model) {
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004209 cpi->denoise_and_model = aom_denoise_and_model_alloc(
4210 cm->seq_params.bit_depth, block_size, noise_level);
Neil Birkbecka2893ab2018-06-08 14:45:13 -07004211 if (!cpi->denoise_and_model) {
4212 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
4213 "Error allocating denoise and model");
4214 return -1;
4215 }
4216 }
4217 if (!cpi->film_grain_table) {
4218 cpi->film_grain_table = aom_malloc(sizeof(*cpi->film_grain_table));
4219 if (!cpi->film_grain_table) {
4220 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
4221 "Error allocating grain table");
4222 return -1;
4223 }
4224 memset(cpi->film_grain_table, 0, sizeof(*cpi->film_grain_table));
4225 }
4226 if (aom_denoise_and_model_run(cpi->denoise_and_model, sd,
4227 &cm->film_grain_params)) {
4228 if (cm->film_grain_params.apply_grain) {
4229 aom_film_grain_table_append(cpi->film_grain_table, time_stamp, end_time,
4230 &cm->film_grain_params);
4231 }
4232 }
4233 return 0;
4234}
4235#endif
4236
James Zern3e2613b2017-03-30 23:14:40 -07004237int av1_receive_raw_frame(AV1_COMP *cpi, aom_enc_frame_flags_t frame_flags,
Yaowu Xuf883b422016-08-30 14:01:10 -07004238 YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
4239 int64_t end_time) {
4240 AV1_COMMON *const cm = &cpi->common;
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004241 const SequenceHeader *const seq_params = &cm->seq_params;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004242 int res = 0;
4243 const int subsampling_x = sd->subsampling_x;
4244 const int subsampling_y = sd->subsampling_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004245 const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004246
sdenge63f9fa2019-12-13 09:29:55 -08004247#if CONFIG_TUNE_VMAF
4248 if (!is_stat_generation_stage(cpi) &&
4249 cpi->oxcf.tuning == AOM_TUNE_VMAF_WITH_PREPROCESSING) {
sdeng615dc242020-02-04 16:06:14 -08004250 av1_vmaf_frame_preprocessing(cpi, sd);
4251 }
4252 if (!is_stat_generation_stage(cpi) &&
4253 cpi->oxcf.tuning == AOM_TUNE_VMAF_MAX_GAIN) {
4254 av1_vmaf_blk_preprocessing(cpi, sd);
sdenge63f9fa2019-12-13 09:29:55 -08004255 }
4256#endif
4257
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004258#if CONFIG_INTERNAL_STATS
4259 struct aom_usec_timer timer;
Yaowu Xuf883b422016-08-30 14:01:10 -07004260 aom_usec_timer_start(&timer);
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004261#endif
Neil Birkbecka2893ab2018-06-08 14:45:13 -07004262#if CONFIG_DENOISE
4263 if (cpi->oxcf.noise_level > 0)
4264 if (apply_denoise_2d(cpi, sd, cpi->oxcf.noise_block_size,
4265 cpi->oxcf.noise_level, time_stamp, end_time) < 0)
4266 res = -1;
4267#endif // CONFIG_DENOISE
4268
Yaowu Xuf883b422016-08-30 14:01:10 -07004269 if (av1_lookahead_push(cpi->lookahead, sd, time_stamp, end_time,
Yaowu Xud3e7c682017-12-21 14:08:25 -08004270 use_highbitdepth, frame_flags))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004271 res = -1;
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004272#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07004273 aom_usec_timer_mark(&timer);
4274 cpi->time_receive_data += aom_usec_timer_elapsed(&timer);
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004275#endif
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004276 if ((seq_params->profile == PROFILE_0) && !seq_params->monochrome &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004277 (subsampling_x != 1 || subsampling_y != 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004278 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -08004279 "Non-4:2:0 color format requires profile 1 or 2");
Yaowu Xuc27fc142016-08-22 16:08:15 -07004280 res = -1;
4281 }
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004282 if ((seq_params->profile == PROFILE_1) &&
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -08004283 !(subsampling_x == 0 && subsampling_y == 0)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004284 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -08004285 "Profile 1 requires 4:4:4 color format");
4286 res = -1;
4287 }
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004288 if ((seq_params->profile == PROFILE_2) &&
4289 (seq_params->bit_depth <= AOM_BITS_10) &&
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -08004290 !(subsampling_x == 1 && subsampling_y == 0)) {
4291 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
4292 "Profile 2 bit-depth < 10 requires 4:2:2 color format");
Yaowu Xuc27fc142016-08-22 16:08:15 -07004293 res = -1;
4294 }
4295
4296 return res;
4297}
4298
Yaowu Xuc27fc142016-08-22 16:08:15 -07004299#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07004300extern double av1_get_blockiness(const unsigned char *img1, int img1_pitch,
4301 const unsigned char *img2, int img2_pitch,
4302 int width, int height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004303
4304static void adjust_image_stat(double y, double u, double v, double all,
4305 ImageStat *s) {
Wan-Teh Changc25c92a2018-04-23 15:04:14 -07004306 s->stat[STAT_Y] += y;
4307 s->stat[STAT_U] += u;
4308 s->stat[STAT_V] += v;
4309 s->stat[STAT_ALL] += all;
Yaowu Xuf883b422016-08-30 14:01:10 -07004310 s->worst = AOMMIN(s->worst, all);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004311}
4312
Angie Chiang08a22a62017-07-17 17:29:17 -07004313static void compute_internal_stats(AV1_COMP *cpi, int frame_bytes) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004314 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004315 double samples = 0.0;
Yaowu Xue75b58a2020-01-03 12:56:12 -08004316 const uint32_t in_bit_depth = cpi->oxcf.input_bit_depth;
4317 const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004318
Angie Chiang08a22a62017-07-17 17:29:17 -07004319#if CONFIG_INTER_STATS_ONLY
David Turnerd2a592e2018-11-16 14:59:31 +00004320 if (cm->current_frame.frame_type == KEY_FRAME) return; // skip key frame
Angie Chiang08a22a62017-07-17 17:29:17 -07004321#endif
4322 cpi->bytes += frame_bytes;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004323 if (cm->show_frame) {
Alex Conversef77fd0b2017-04-20 11:00:24 -07004324 const YV12_BUFFER_CONFIG *orig = cpi->source;
David Turnerc29e1a92018-12-06 14:10:14 +00004325 const YV12_BUFFER_CONFIG *recon = &cpi->common.cur_frame->buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004326 double y, u, v, frame_all;
4327
4328 cpi->count++;
4329 if (cpi->b_calculate_psnr) {
4330 PSNR_STATS psnr;
4331 double frame_ssim2 = 0.0, weight = 0.0;
Yaowu Xuf883b422016-08-30 14:01:10 -07004332 aom_clear_system_state();
Jerome Jiangfa1d1732019-08-06 10:31:20 -07004333#if CONFIG_AV1_HIGHBITDEPTH
Yaowu Xue75b58a2020-01-03 12:56:12 -08004334 aom_calc_highbd_psnr(orig, recon, &psnr, bit_depth, in_bit_depth);
Jerome Jiangfa1d1732019-08-06 10:31:20 -07004335#else
4336 aom_calc_psnr(orig, recon, &psnr);
4337#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004338 adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], psnr.psnr[0],
4339 &cpi->psnr);
4340 cpi->total_sq_error += psnr.sse[0];
4341 cpi->total_samples += psnr.samples[0];
4342 samples = psnr.samples[0];
Yaowu Xud3e7c682017-12-21 14:08:25 -08004343 // TODO(yaowu): unify these two versions into one.
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004344 if (cm->seq_params.use_highbitdepth)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004345 frame_ssim2 =
Yaowu Xuf883b422016-08-30 14:01:10 -07004346 aom_highbd_calc_ssim(orig, recon, &weight, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004347 else
Yaowu Xuf883b422016-08-30 14:01:10 -07004348 frame_ssim2 = aom_calc_ssim(orig, recon, &weight);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004349
Yaowu Xuf883b422016-08-30 14:01:10 -07004350 cpi->worst_ssim = AOMMIN(cpi->worst_ssim, frame_ssim2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004351 cpi->summed_quality += frame_ssim2 * weight;
4352 cpi->summed_weights += weight;
4353
4354#if 0
4355 {
4356 FILE *f = fopen("q_used.stt", "a");
Zoe Liuee202be2017-11-17 12:14:33 -08004357 double y2 = psnr.psnr[1];
4358 double u2 = psnr.psnr[2];
4359 double v2 = psnr.psnr[3];
4360 double frame_psnr2 = psnr.psnr[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004361 fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
David Turnerd2a592e2018-11-16 14:59:31 +00004362 cm->current_frame.frame_number, y2, u2, v2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004363 frame_psnr2, frame_ssim2);
4364 fclose(f);
4365 }
4366#endif
4367 }
4368 if (cpi->b_calculate_blockiness) {
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004369 if (!cm->seq_params.use_highbitdepth) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004370 const double frame_blockiness =
Yaowu Xuf883b422016-08-30 14:01:10 -07004371 av1_get_blockiness(orig->y_buffer, orig->y_stride, recon->y_buffer,
4372 recon->y_stride, orig->y_width, orig->y_height);
4373 cpi->worst_blockiness = AOMMAX(cpi->worst_blockiness, frame_blockiness);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004374 cpi->total_blockiness += frame_blockiness;
4375 }
4376
4377 if (cpi->b_calculate_consistency) {
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004378 if (!cm->seq_params.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004379 const double this_inconsistency = aom_get_ssim_metrics(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004380 orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride,
4381 orig->y_width, orig->y_height, cpi->ssim_vars, &cpi->metrics, 1);
4382
4383 const double peak = (double)((1 << in_bit_depth) - 1);
4384 const double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07004385 aom_sse_to_psnr(samples, peak, cpi->total_inconsistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004386 if (consistency > 0.0)
4387 cpi->worst_consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07004388 AOMMIN(cpi->worst_consistency, consistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004389 cpi->total_inconsistency += this_inconsistency;
4390 }
4391 }
4392 }
4393
4394 frame_all =
Yaowu Xuf883b422016-08-30 14:01:10 -07004395 aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004396 adjust_image_stat(y, u, v, frame_all, &cpi->fastssim);
Yaowu Xuf883b422016-08-30 14:01:10 -07004397 frame_all = aom_psnrhvs(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004398 adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs);
4399 }
4400}
4401#endif // CONFIG_INTERNAL_STATS
Wan-Teh Chang1c520052020-06-11 10:17:56 -07004402
Andrey Norkin795ba872018-03-06 13:24:14 -08004403int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
4404 size_t *size, uint8_t *dest, int64_t *time_stamp,
4405 int64_t *time_end, int flush,
Yue Chen1bc5be62018-08-24 13:57:32 -07004406 const aom_rational64_t *timestamp_ratio) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004407 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
4408 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004409
4410#if CONFIG_BITSTREAM_DEBUG
Urvang Joshie2b505b2020-06-19 11:39:49 -07004411 assert(cpi->oxcf.max_threads <= 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004412 "bitstream debug tool does not support multithreading");
4413 bitstream_queue_record_write();
Yaowu Xu63f2ea32019-04-29 10:47:42 -07004414 aom_bitstream_queue_set_frame_write(cm->current_frame.frame_number * 2 +
4415 cm->show_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004416#endif
Marco Paniconi63971322019-08-15 21:32:05 -07004417 if (cpi->use_svc && cm->number_spatial_layers > 1) {
4418 av1_one_pass_cbr_svc_start_layer(cpi);
4419 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004420
Dominic Symesd4929012018-01-31 17:32:01 +01004421 cm->showable_frame = 0;
David Turnere43f7fe2019-01-15 14:58:00 +00004422 *size = 0;
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004423#if CONFIG_INTERNAL_STATS
4424 struct aom_usec_timer cmptimer;
Yaowu Xuf883b422016-08-30 14:01:10 -07004425 aom_usec_timer_start(&cmptimer);
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004426#endif
chiyotsaic666b1f2019-12-20 10:44:58 -08004427 av1_set_high_precision_mv(cpi, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004428
Debargha Mukherjeeba7b8fe2018-03-15 23:10:07 -07004429 // Normal defaults
Urvang Joshi6237b882020-03-26 15:02:26 -07004430 cm->features.refresh_frame_context = oxcf->frame_parallel_decoding_mode
4431 ? REFRESH_FRAME_CONTEXT_DISABLED
4432 : REFRESH_FRAME_CONTEXT_BACKWARD;
Vishesh0481a782020-06-11 14:32:46 +05304433 if (oxcf->tile_cfg.enable_large_scale_tile)
Urvang Joshi6237b882020-03-26 15:02:26 -07004434 cm->features.refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004435
Sarah Parkerb9041612018-05-22 19:06:47 -07004436 // Initialize fields related to forward keyframes
Sarah Parkeraf32a7b2018-06-29 14:59:05 -07004437 cpi->no_show_kf = 0;
Zoe Liub4991202017-12-21 15:31:06 -08004438
David Turnerdedd8ff2019-01-23 13:59:46 +00004439 if (assign_cur_frame_new_fb(cm) == NULL) return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004440
Yue Chen1bc5be62018-08-24 13:57:32 -07004441 const int result =
4442 av1_encode_strategy(cpi, size, dest, frame_flags, time_stamp, time_end,
4443 timestamp_ratio, flush);
Wan-Teh Chang1c520052020-06-11 10:17:56 -07004444 if (result == -1) {
David Turnerdedd8ff2019-01-23 13:59:46 +00004445 // Returning -1 indicates no frame encoded; more input is required
4446 return -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004447 }
Wan-Teh Chang1c520052020-06-11 10:17:56 -07004448 if (result != AOM_CODEC_OK) {
4449 return AOM_CODEC_ERROR;
4450 }
Yunqing Wangd1f32e62019-02-20 10:37:51 -08004451#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07004452 aom_usec_timer_mark(&cmptimer);
4453 cpi->time_compress_data += aom_usec_timer_elapsed(&cmptimer);
Yue Chen1bc5be62018-08-24 13:57:32 -07004454#endif // CONFIG_INTERNAL_STATS
David Turnerc4bf8c72019-01-15 13:14:37 +00004455 if (cpi->b_calculate_psnr) {
Mufaddal Chakerae7326122019-12-04 14:49:09 +05304456 if (cm->show_existing_frame ||
4457 (!is_stat_generation_stage(cpi) && cm->show_frame)) {
David Turnerc4bf8c72019-01-15 13:14:37 +00004458 generate_psnr_packet(cpi);
4459 }
4460 }
Hui Su8ea87322019-03-29 14:44:32 -07004461
sdeng3cd9eec2020-01-23 15:49:50 -08004462#if CONFIG_TUNE_VMAF
sdeng995c54e2020-02-18 14:51:00 -08004463 if (!is_stat_generation_stage(cpi) &&
4464 (oxcf->tuning == AOM_TUNE_VMAF_WITH_PREPROCESSING ||
4465 oxcf->tuning == AOM_TUNE_VMAF_WITHOUT_PREPROCESSING ||
4466 oxcf->tuning == AOM_TUNE_VMAF_MAX_GAIN)) {
4467 av1_update_vmaf_curve(cpi, cpi->source, &cpi->common.cur_frame->buf);
sdeng3cd9eec2020-01-23 15:49:50 -08004468 }
4469#endif
4470
Vishesh8ac928b2020-04-01 02:36:35 +05304471 if (cpi->level_params.keep_level_stats && !is_stat_generation_stage(cpi)) {
Hui Su8ea87322019-03-29 14:44:32 -07004472 // Initialize level info. at the beginning of each sequence.
4473 if (cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) {
Hui Su58753d62019-05-29 09:56:19 -07004474 av1_init_level_info(cpi);
Hui Su8ea87322019-03-29 14:44:32 -07004475 }
kyslovabeeb7c2019-03-06 18:35:04 -08004476 av1_update_level_info(cpi, *size, *time_stamp, *time_end);
Hui Su8ea87322019-03-29 14:44:32 -07004477 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004478
4479#if CONFIG_INTERNAL_STATS
Mufaddal Chakerae7326122019-12-04 14:49:09 +05304480 if (!is_stat_generation_stage(cpi)) {
Angie Chiang08a22a62017-07-17 17:29:17 -07004481 compute_internal_stats(cpi, (int)(*size));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004482 }
4483#endif // CONFIG_INTERNAL_STATS
Debargha Mukherjee0857e662019-01-04 16:22:09 -08004484#if CONFIG_SPEED_STATS
Mufaddal Chakerae7326122019-12-04 14:49:09 +05304485 if (!is_stat_generation_stage(cpi) && !cm->show_existing_frame) {
chiyotsai4c1e5c62020-04-30 17:54:14 -07004486 cpi->tx_search_count += cpi->td.mb.txfm_search_info.tx_search_count;
4487 cpi->td.mb.txfm_search_info.tx_search_count = 0;
Debargha Mukherjee0857e662019-01-04 16:22:09 -08004488 }
4489#endif // CONFIG_SPEED_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004490
Yaowu Xuf883b422016-08-30 14:01:10 -07004491 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004492
Hui Su0d0ee662019-07-29 14:38:36 -07004493 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004494}
4495
Yaowu Xuf883b422016-08-30 14:01:10 -07004496int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest) {
4497 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004498 if (!cm->show_frame) {
4499 return -1;
4500 } else {
4501 int ret;
David Turnerc29e1a92018-12-06 14:10:14 +00004502 if (cm->cur_frame != NULL) {
4503 *dest = cm->cur_frame->buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004504 dest->y_width = cm->width;
4505 dest->y_height = cm->height;
Urvang Joshi20cf30e2018-07-19 02:33:58 -07004506 dest->uv_width = cm->width >> cm->seq_params.subsampling_x;
4507 dest->uv_height = cm->height >> cm->seq_params.subsampling_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004508 ret = 0;
4509 } else {
4510 ret = -1;
4511 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004512 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004513 return ret;
4514 }
4515}
4516
Yaowu Xuf883b422016-08-30 14:01:10 -07004517int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame) {
David Turnere7ebf902018-12-04 14:04:55 +00004518 if (cpi->last_show_frame_buf == NULL) return -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004519
David Turnere7ebf902018-12-04 14:04:55 +00004520 *frame = cpi->last_show_frame_buf->buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004521 return 0;
4522}
4523
Yunqing Wang93b18f32018-06-08 21:08:29 -07004524aom_codec_err_t av1_copy_new_frame_enc(AV1_COMMON *cm,
4525 YV12_BUFFER_CONFIG *new_frame,
4526 YV12_BUFFER_CONFIG *sd) {
Yunqing Wangff9bfca2018-06-06 11:46:08 -07004527 const int num_planes = av1_num_planes(cm);
4528 if (!equal_dimensions_and_border(new_frame, sd))
4529 aom_internal_error(&cm->error, AOM_CODEC_ERROR,
4530 "Incorrect buffer dimensions");
4531 else
4532 aom_yv12_copy_frame(new_frame, sd, num_planes);
4533
4534 return cm->error.error_code;
4535}
4536
Jayasanker J0b1dd292020-04-09 15:47:25 +05304537int av1_set_internal_size(AV1EncoderConfig *const oxcf,
4538 ResizePendingParams *resize_pending_params,
4539 AOM_SCALING horiz_mode, AOM_SCALING vert_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004540 int hr = 0, hs = 0, vr = 0, vs = 0;
4541
4542 if (horiz_mode > ONETWO || vert_mode > ONETWO) return -1;
4543
4544 Scale2Ratio(horiz_mode, &hr, &hs);
4545 Scale2Ratio(vert_mode, &vr, &vs);
4546
4547 // always go to the next whole number
Vishesh2b8e4792020-06-12 12:11:19 +05304548 resize_pending_params->width = (hs - 1 + oxcf->frm_dim_cfg.width * hr) / hs;
4549 resize_pending_params->height = (vs - 1 + oxcf->frm_dim_cfg.height * vr) / vs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004550
Marco Paniconi72056922020-06-24 12:31:25 -07004551 if (horiz_mode != NORMAL || vert_mode != NORMAL)
4552 oxcf->resize_cfg.resize_mode = RESIZE_FIXED;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004553 return 0;
4554}
4555
Urvang Joshi17814622020-03-27 17:26:17 -07004556int av1_get_quantizer(AV1_COMP *cpi) {
4557 return cpi->common.quant_params.base_qindex;
4558}
Yaowu Xuc27fc142016-08-22 16:08:15 -07004559
Soo-Chul Han29c46fb2018-03-23 16:02:00 -04004560int av1_convert_sect5obus_to_annexb(uint8_t *buffer, size_t *frame_size) {
4561 size_t output_size = 0;
4562 size_t total_bytes_read = 0;
4563 size_t remaining_size = *frame_size;
4564 uint8_t *buff_ptr = buffer;
4565
4566 // go through each OBUs
4567 while (total_bytes_read < *frame_size) {
4568 uint8_t saved_obu_header[2];
4569 uint64_t obu_payload_size;
4570 size_t length_of_payload_size;
4571 size_t length_of_obu_size;
4572 uint32_t obu_header_size = (buff_ptr[0] >> 2) & 0x1 ? 2 : 1;
4573 size_t obu_bytes_read = obu_header_size; // bytes read for current obu
4574
4575 // save the obu header (1 or 2 bytes)
4576 memmove(saved_obu_header, buff_ptr, obu_header_size);
4577 // clear the obu_has_size_field
4578 saved_obu_header[0] = saved_obu_header[0] & (~0x2);
4579
4580 // get the payload_size and length of payload_size
4581 if (aom_uleb_decode(buff_ptr + obu_header_size, remaining_size,
4582 &obu_payload_size, &length_of_payload_size) != 0) {
4583 return AOM_CODEC_ERROR;
4584 }
4585 obu_bytes_read += length_of_payload_size;
4586
4587 // calculate the length of size of the obu header plus payload
4588 length_of_obu_size =
4589 aom_uleb_size_in_bytes((uint64_t)(obu_header_size + obu_payload_size));
4590
4591 // move the rest of data to new location
4592 memmove(buff_ptr + length_of_obu_size + obu_header_size,
4593 buff_ptr + obu_bytes_read, remaining_size - obu_bytes_read);
Yaowu Xu9e494202018-04-03 11:19:49 -07004594 obu_bytes_read += (size_t)obu_payload_size;
Soo-Chul Han29c46fb2018-03-23 16:02:00 -04004595
4596 // write the new obu size
4597 const uint64_t obu_size = obu_header_size + obu_payload_size;
4598 size_t coded_obu_size;
4599 if (aom_uleb_encode(obu_size, sizeof(obu_size), buff_ptr,
4600 &coded_obu_size) != 0) {
4601 return AOM_CODEC_ERROR;
4602 }
4603
4604 // write the saved (modified) obu_header following obu size
4605 memmove(buff_ptr + length_of_obu_size, saved_obu_header, obu_header_size);
4606
4607 total_bytes_read += obu_bytes_read;
4608 remaining_size -= obu_bytes_read;
4609 buff_ptr += length_of_obu_size + obu_size;
Yaowu Xu9e494202018-04-03 11:19:49 -07004610 output_size += length_of_obu_size + (size_t)obu_size;
Soo-Chul Han29c46fb2018-03-23 16:02:00 -04004611 }
4612
4613 *frame_size = output_size;
4614 return AOM_CODEC_OK;
4615}
4616
Vishesha195ca32020-04-07 18:46:20 +05304617static void svc_set_updates_external_ref_frame_config(
Vishesh38c05d72020-04-14 12:19:14 +05304618 ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags, SVC *const svc) {
4619 ext_refresh_frame_flags->update_pending = 1;
4620 ext_refresh_frame_flags->last_frame = svc->refresh[svc->ref_idx[0]];
4621 ext_refresh_frame_flags->golden_frame = svc->refresh[svc->ref_idx[3]];
4622 ext_refresh_frame_flags->bwd_ref_frame = svc->refresh[svc->ref_idx[4]];
4623 ext_refresh_frame_flags->alt2_ref_frame = svc->refresh[svc->ref_idx[5]];
4624 ext_refresh_frame_flags->alt_ref_frame = svc->refresh[svc->ref_idx[6]];
Vishesha195ca32020-04-07 18:46:20 +05304625 svc->non_reference_frame = 1;
Marco Paniconid8574e32019-08-04 21:30:12 -07004626 for (int i = 0; i < REF_FRAMES; i++) {
Vishesha195ca32020-04-07 18:46:20 +05304627 if (svc->refresh[i] == 1) {
4628 svc->non_reference_frame = 0;
Marco Paniconid8574e32019-08-04 21:30:12 -07004629 break;
4630 }
4631 }
4632}
4633
Marco Paniconiad4953a2020-04-02 09:52:58 -07004634static int svc_set_references_external_ref_frame_config(AV1_COMP *cpi) {
4635 // LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), GOLDEN_FRAME(3),
4636 // BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6).
4637 int ref = AOM_REFFRAME_ALL;
4638 for (int i = 0; i < INTER_REFS_PER_FRAME; i++) {
4639 if (!cpi->svc.reference[i]) ref ^= (1 << i);
4640 }
4641 return ref;
4642}
4643
Yaowu Xuf883b422016-08-30 14:01:10 -07004644void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {
Yunqing Wang9a50fec2017-11-02 17:02:00 -07004645 // TODO(yunqingwang): For what references to use, external encoding flags
4646 // should be consistent with internal reference frame selection. Need to
4647 // ensure that there is not conflict between the two. In AV1 encoder, the
4648 // priority rank for 7 reference frames are: LAST, ALTREF, LAST2, LAST3,
Marco Paniconi60a4d7f2019-08-02 14:43:27 -07004649 // GOLDEN, BWDREF, ALTREF2.
Vishesha195ca32020-04-07 18:46:20 +05304650
4651 ExternalFlags *const ext_flags = &cpi->ext_flags;
Vishesh38c05d72020-04-14 12:19:14 +05304652 ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
4653 &ext_flags->refresh_frame;
Vishesha195ca32020-04-07 18:46:20 +05304654 ext_flags->ref_frame_flags = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004655 if (flags &
Yunqing Wang9a50fec2017-11-02 17:02:00 -07004656 (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
4657 AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
4658 AOM_EFLAG_NO_REF_ARF2)) {
Marco Paniconi60a4d7f2019-08-02 14:43:27 -07004659 int ref = AOM_REFFRAME_ALL;
4660
4661 if (flags & AOM_EFLAG_NO_REF_LAST) ref ^= AOM_LAST_FLAG;
4662 if (flags & AOM_EFLAG_NO_REF_LAST2) ref ^= AOM_LAST2_FLAG;
4663 if (flags & AOM_EFLAG_NO_REF_LAST3) ref ^= AOM_LAST3_FLAG;
4664
4665 if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
4666
4667 if (flags & AOM_EFLAG_NO_REF_ARF) {
4668 ref ^= AOM_ALT_FLAG;
4669 ref ^= AOM_BWD_FLAG;
4670 ref ^= AOM_ALT2_FLAG;
Yunqing Wang9a50fec2017-11-02 17:02:00 -07004671 } else {
Marco Paniconi60a4d7f2019-08-02 14:43:27 -07004672 if (flags & AOM_EFLAG_NO_REF_BWD) ref ^= AOM_BWD_FLAG;
4673 if (flags & AOM_EFLAG_NO_REF_ARF2) ref ^= AOM_ALT2_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004674 }
Marco Paniconi60a4d7f2019-08-02 14:43:27 -07004675
Vishesha195ca32020-04-07 18:46:20 +05304676 av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
Marco Paniconiad4953a2020-04-02 09:52:58 -07004677 } else {
4678 if (cpi->svc.external_ref_frame_config) {
4679 int ref = svc_set_references_external_ref_frame_config(cpi);
Vishesha195ca32020-04-07 18:46:20 +05304680 av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
Marco Paniconiad4953a2020-04-02 09:52:58 -07004681 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004682 }
4683
4684 if (flags &
Yunqing Wang9a50fec2017-11-02 17:02:00 -07004685 (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004686 int upd = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004687
Yunqing Wang9a50fec2017-11-02 17:02:00 -07004688 // Refreshing LAST/LAST2/LAST3 is handled by 1 common flag.
4689 if (flags & AOM_EFLAG_NO_UPD_LAST) upd ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004690
Yaowu Xuf883b422016-08-30 14:01:10 -07004691 if (flags & AOM_EFLAG_NO_UPD_GF) upd ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004692
Yunqing Wang9a50fec2017-11-02 17:02:00 -07004693 if (flags & AOM_EFLAG_NO_UPD_ARF) {
4694 upd ^= AOM_ALT_FLAG;
4695 upd ^= AOM_BWD_FLAG;
4696 upd ^= AOM_ALT2_FLAG;
4697 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698
Vishesh38c05d72020-04-14 12:19:14 +05304699 ext_refresh_frame_flags->last_frame = (upd & AOM_LAST_FLAG) != 0;
4700 ext_refresh_frame_flags->golden_frame = (upd & AOM_GOLD_FLAG) != 0;
4701 ext_refresh_frame_flags->alt_ref_frame = (upd & AOM_ALT_FLAG) != 0;
4702 ext_refresh_frame_flags->bwd_ref_frame = (upd & AOM_BWD_FLAG) != 0;
4703 ext_refresh_frame_flags->alt2_ref_frame = (upd & AOM_ALT2_FLAG) != 0;
4704 ext_refresh_frame_flags->update_pending = 1;
David Turner4f1f1812019-01-24 17:00:24 +00004705 } else {
Marco Paniconid8574e32019-08-04 21:30:12 -07004706 if (cpi->svc.external_ref_frame_config)
Vishesh38c05d72020-04-14 12:19:14 +05304707 svc_set_updates_external_ref_frame_config(ext_refresh_frame_flags,
4708 &cpi->svc);
Marco Paniconid8574e32019-08-04 21:30:12 -07004709 else
Vishesh38c05d72020-04-14 12:19:14 +05304710 ext_refresh_frame_flags->update_pending = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004711 }
4712
Vishesha195ca32020-04-07 18:46:20 +05304713 ext_flags->use_ref_frame_mvs = cpi->oxcf.allow_ref_frame_mvs &
4714 ((flags & AOM_EFLAG_NO_REF_FRAME_MVS) == 0);
4715 ext_flags->use_error_resilient = cpi->oxcf.error_resilient_mode |
4716 ((flags & AOM_EFLAG_ERROR_RESILIENT) != 0);
4717 ext_flags->use_s_frame =
Vishesh7e9873d2020-06-08 15:41:33 +05304718 cpi->oxcf.kf_cfg.enable_sframe | ((flags & AOM_EFLAG_SET_S_FRAME) != 0);
Vishesha195ca32020-04-07 18:46:20 +05304719 ext_flags->use_primary_ref_none =
4720 (flags & AOM_EFLAG_SET_PRIMARY_REF_NONE) != 0;
sarahparker21dbca42018-03-30 17:43:44 -07004721
Yaowu Xuf883b422016-08-30 14:01:10 -07004722 if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
Satish Kumar Suman329de4d2020-06-16 10:48:32 +05304723 update_entropy(&ext_flags->refresh_frame_context,
4724 &ext_flags->refresh_frame_context_pending, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004725 }
4726}
Andrey Norkin795ba872018-03-06 13:24:14 -08004727
Tom Fineganf8d6a162018-08-21 10:47:55 -07004728aom_fixed_buf_t *av1_get_global_headers(AV1_COMP *cpi) {
4729 if (!cpi) return NULL;
4730
4731 uint8_t header_buf[512] = { 0 };
4732 const uint32_t sequence_header_size =
Urvang Joshi450a9a22020-03-31 16:00:22 -07004733 av1_write_sequence_header_obu(&cpi->common.seq_params, &header_buf[0]);
Tom Fineganf8d6a162018-08-21 10:47:55 -07004734 assert(sequence_header_size <= sizeof(header_buf));
4735 if (sequence_header_size == 0) return NULL;
4736
4737 const size_t obu_header_size = 1;
4738 const size_t size_field_size = aom_uleb_size_in_bytes(sequence_header_size);
4739 const size_t payload_offset = obu_header_size + size_field_size;
4740
4741 if (payload_offset + sequence_header_size > sizeof(header_buf)) return NULL;
4742 memmove(&header_buf[payload_offset], &header_buf[0], sequence_header_size);
4743
Vishesh8ac928b2020-04-01 02:36:35 +05304744 if (av1_write_obu_header(&cpi->level_params, OBU_SEQUENCE_HEADER, 0,
4745 &header_buf[0]) != obu_header_size) {
Tom Fineganf8d6a162018-08-21 10:47:55 -07004746 return NULL;
4747 }
4748
4749 size_t coded_size_field_size = 0;
4750 if (aom_uleb_encode(sequence_header_size, size_field_size,
4751 &header_buf[obu_header_size],
4752 &coded_size_field_size) != 0) {
4753 return NULL;
4754 }
4755 assert(coded_size_field_size == size_field_size);
4756
4757 aom_fixed_buf_t *global_headers =
4758 (aom_fixed_buf_t *)malloc(sizeof(*global_headers));
4759 if (!global_headers) return NULL;
4760
4761 const size_t global_header_buf_size =
4762 obu_header_size + size_field_size + sequence_header_size;
4763
4764 global_headers->buf = malloc(global_header_buf_size);
4765 if (!global_headers->buf) {
4766 free(global_headers);
4767 return NULL;
4768 }
4769
4770 memcpy(global_headers->buf, &header_buf[0], global_header_buf_size);
4771 global_headers->sz = global_header_buf_size;
4772 return global_headers;
4773}