blob: f33761161792afddfab55c2dc733f43264987666 [file] [log] [blame]
David Turner056f7cd2019-01-07 17:48:13 +00001/*
2 * Copyright (c) 2019, Alliance for Open Media. All rights reserved
3 *
4 * 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.
10 */
11
12#include <stdint.h>
13
bohanli2541b8a2020-10-14 17:33:13 -070014#include "av1/common/blockd.h"
David Turner1539bb02019-01-24 15:28:13 +000015#include "config/aom_config.h"
David Turnerdedd8ff2019-01-23 13:59:46 +000016#include "config/aom_scale_rtcd.h"
David Turner1539bb02019-01-24 15:28:13 +000017
David Turner056f7cd2019-01-07 17:48:13 +000018#include "aom/aom_codec.h"
David Turnerdedd8ff2019-01-23 13:59:46 +000019#include "aom/aom_encoder.h"
20
21#include "aom_ports/system_state.h"
David Turner056f7cd2019-01-07 17:48:13 +000022
David Turner1539bb02019-01-24 15:28:13 +000023#if CONFIG_MISMATCH_DEBUG
24#include "aom_util/debug_util.h"
25#endif // CONFIG_MISMATCH_DEBUG
26
Wan-Teh Changf2d15ee2020-03-10 09:24:43 -070027#include "av1/common/av1_common_int.h"
Cheng Chen5083a9f2019-07-12 15:33:34 -070028#include "av1/common/reconinter.h"
David Turner07dbd8e2019-01-08 17:16:25 +000029
David Turner056f7cd2019-01-07 17:48:13 +000030#include "av1/encoder/encoder.h"
31#include "av1/encoder/encode_strategy.h"
Cheng Chen5083a9f2019-07-12 15:33:34 -070032#include "av1/encoder/encodeframe.h"
David Turner475a3132019-01-18 15:17:17 +000033#include "av1/encoder/firstpass.h"
David Turner0fa8c492019-02-06 16:38:13 +000034#include "av1/encoder/pass2_strategy.h"
David Turnerdedd8ff2019-01-23 13:59:46 +000035#include "av1/encoder/temporal_filter.h"
David Turner475a3132019-01-18 15:17:17 +000036#include "av1/encoder/tpl_model.h"
David Turner056f7cd2019-01-07 17:48:13 +000037
Sai Dengaff27722020-08-31 12:06:09 -070038#if CONFIG_TUNE_VMAF
39#include "av1/encoder/tune_vmaf.h"
40#endif
41
Cheng Chen7abe3132019-06-19 11:55:28 -070042#define TEMPORAL_FILTER_KEY_FRAME (CONFIG_REALTIME_ONLY ? 0 : 1)
43
Jayasanker J24cb9bc2020-04-15 13:43:10 +053044static INLINE void set_refresh_frame_flags(
45 RefreshFrameFlagsInfo *const refresh_frame_flags, bool refresh_gf,
46 bool refresh_bwdref, bool refresh_arf) {
47 refresh_frame_flags->golden_frame = refresh_gf;
48 refresh_frame_flags->bwd_ref_frame = refresh_bwdref;
49 refresh_frame_flags->alt_ref_frame = refresh_arf;
50}
51
52void av1_configure_buffer_updates(
53 AV1_COMP *const cpi, RefreshFrameFlagsInfo *const refresh_frame_flags,
bohanli99852502020-07-14 16:22:45 -070054 const FRAME_UPDATE_TYPE type, const FRAME_TYPE frame_type,
55 int force_refresh_all) {
David Turnerce9b5902019-01-23 17:25:47 +000056 // NOTE(weitinglin): Should we define another function to take care of
57 // cpi->rc.is_$Source_Type to make this function as it is in the comment?
58
Vishesh38c05d72020-04-14 12:19:14 +053059 const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
60 &cpi->ext_flags.refresh_frame;
David Turner4f1f1812019-01-24 17:00:24 +000061 cpi->rc.is_src_frame_alt_ref = 0;
David Turnerce9b5902019-01-23 17:25:47 +000062
63 switch (type) {
64 case KF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053065 set_refresh_frame_flags(refresh_frame_flags, true, true, true);
David Turnerce9b5902019-01-23 17:25:47 +000066 break;
67
68 case LF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053069 set_refresh_frame_flags(refresh_frame_flags, false, false, false);
David Turnerce9b5902019-01-23 17:25:47 +000070 break;
71
72 case GF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053073 set_refresh_frame_flags(refresh_frame_flags, true, false, false);
David Turnerce9b5902019-01-23 17:25:47 +000074 break;
75
76 case OVERLAY_UPDATE:
bohanli2541b8a2020-10-14 17:33:13 -070077 if (frame_type == KEY_FRAME && cpi->rc.frames_to_key == 0) {
78 set_refresh_frame_flags(refresh_frame_flags, true, true, true);
79 } else {
80 set_refresh_frame_flags(refresh_frame_flags, true, false, false);
81 }
David Turnerce9b5902019-01-23 17:25:47 +000082 cpi->rc.is_src_frame_alt_ref = 1;
83 break;
84
85 case ARF_UPDATE:
David Turnerce9b5902019-01-23 17:25:47 +000086 // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
bohanli99852502020-07-14 16:22:45 -070087 if (frame_type == KEY_FRAME && !cpi->no_show_fwd_kf) {
88 // TODO(bohanli): consider moving this to force_refresh_all?
89 // This is Keyframe as arf
90 set_refresh_frame_flags(refresh_frame_flags, true, true, true);
91 } else {
92 set_refresh_frame_flags(refresh_frame_flags, false, false, true);
93 }
David Turnerce9b5902019-01-23 17:25:47 +000094 break;
95
David Turnerce9b5902019-01-23 17:25:47 +000096 case INTNL_OVERLAY_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053097 set_refresh_frame_flags(refresh_frame_flags, false, false, false);
David Turnerce9b5902019-01-23 17:25:47 +000098 cpi->rc.is_src_frame_alt_ref = 1;
David Turnerce9b5902019-01-23 17:25:47 +000099 break;
100
101 case INTNL_ARF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530102 set_refresh_frame_flags(refresh_frame_flags, false, true, false);
David Turnerce9b5902019-01-23 17:25:47 +0000103 break;
104
105 default: assert(0); break;
106 }
David Turner4f1f1812019-01-24 17:00:24 +0000107
Vishesh38c05d72020-04-14 12:19:14 +0530108 if (ext_refresh_frame_flags->update_pending &&
Jingning Hana862e202021-05-14 10:18:50 -0700109 (!is_stat_generation_stage(cpi))) {
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530110 set_refresh_frame_flags(refresh_frame_flags,
111 ext_refresh_frame_flags->golden_frame,
112 ext_refresh_frame_flags->bwd_ref_frame,
113 ext_refresh_frame_flags->alt_ref_frame);
Jingning Hana862e202021-05-14 10:18:50 -0700114 GF_GROUP *gf_group = &cpi->ppi->gf_group;
115 if (ext_refresh_frame_flags->golden_frame)
116 gf_group->update_type[cpi->gf_frame_index] = GF_UPDATE;
117 if (ext_refresh_frame_flags->alt_ref_frame)
118 gf_group->update_type[cpi->gf_frame_index] = ARF_UPDATE;
119 if (ext_refresh_frame_flags->bwd_ref_frame)
120 gf_group->update_type[cpi->gf_frame_index] = INTNL_ARF_UPDATE;
121 }
David Turner4f1f1812019-01-24 17:00:24 +0000122
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530123 if (force_refresh_all)
124 set_refresh_frame_flags(refresh_frame_flags, true, true, true);
David Turnerce9b5902019-01-23 17:25:47 +0000125}
126
David Turner1539bb02019-01-24 15:28:13 +0000127static void set_additional_frame_flags(const AV1_COMMON *const cm,
128 unsigned int *const frame_flags) {
Urvang Joshib6409e92020-03-23 11:23:27 -0700129 if (frame_is_intra_only(cm)) {
130 *frame_flags |= FRAMEFLAGS_INTRAONLY;
131 }
132 if (frame_is_sframe(cm)) {
133 *frame_flags |= FRAMEFLAGS_SWITCH;
134 }
135 if (cm->features.error_resilient_mode) {
136 *frame_flags |= FRAMEFLAGS_ERROR_RESILIENT;
137 }
David Turner1539bb02019-01-24 15:28:13 +0000138}
139
140static INLINE void update_keyframe_counters(AV1_COMP *cpi) {
Jingning Hanac2c30b2020-12-04 13:18:22 -0800141 if (cpi->common.show_frame && cpi->rc.frames_to_key) {
Jingning Han6d3777b2020-09-29 16:21:24 -0700142 cpi->rc.frames_since_key++;
143 cpi->rc.frames_to_key--;
David Turner1539bb02019-01-24 15:28:13 +0000144 }
145}
146
Vishesh38c05d72020-04-14 12:19:14 +0530147static INLINE int is_frame_droppable(
148 const SVC *const svc,
149 const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags) {
Jingning Han98d20de2019-08-14 12:59:47 -0700150 // Droppable frame is only used by external refresh flags. VoD setting won't
151 // trigger its use case.
Marco Paniconie5de3322021-03-22 22:03:17 -0700152 if (svc->set_ref_frame_config)
Vishesha195ca32020-04-07 18:46:20 +0530153 return svc->non_reference_frame;
Vishesh38c05d72020-04-14 12:19:14 +0530154 else if (ext_refresh_frame_flags->update_pending)
155 return !(ext_refresh_frame_flags->alt_ref_frame ||
156 ext_refresh_frame_flags->alt2_ref_frame ||
157 ext_refresh_frame_flags->bwd_ref_frame ||
158 ext_refresh_frame_flags->golden_frame ||
159 ext_refresh_frame_flags->last_frame);
Marco Paniconi91a50022019-08-01 18:56:39 -0700160 else
Jingning Han98d20de2019-08-14 12:59:47 -0700161 return 0;
David Turner1539bb02019-01-24 15:28:13 +0000162}
163
164static INLINE void update_frames_till_gf_update(AV1_COMP *cpi) {
165 // TODO(weitinglin): Updating this counter for is_frame_droppable
166 // is a work-around to handle the condition when a frame is drop.
167 // We should fix the cpi->common.show_frame flag
168 // instead of checking the other condition to update the counter properly.
Vishesha195ca32020-04-07 18:46:20 +0530169 if (cpi->common.show_frame ||
Vishesh38c05d72020-04-14 12:19:14 +0530170 is_frame_droppable(&cpi->svc, &cpi->ext_flags.refresh_frame)) {
David Turner1539bb02019-01-24 15:28:13 +0000171 // Decrement count down till next gf
172 if (cpi->rc.frames_till_gf_update_due > 0)
173 cpi->rc.frames_till_gf_update_due--;
174 }
175}
176
Sarah Parker97803fc2019-05-17 14:15:37 -0700177static INLINE void update_gf_group_index(AV1_COMP *cpi) {
Jingning Han16fafcb2020-09-29 23:23:13 -0700178 // Increment the gf group index ready for the next frame.
Mufaddal Chakeraab20d372021-03-17 12:18:34 +0530179 ++cpi->gf_frame_index;
David Turner1539bb02019-01-24 15:28:13 +0000180}
181
182static void update_rc_counts(AV1_COMP *cpi) {
183 update_keyframe_counters(cpi);
184 update_frames_till_gf_update(cpi);
Sarah Parker97803fc2019-05-17 14:15:37 -0700185 update_gf_group_index(cpi);
David Turner1539bb02019-01-24 15:28:13 +0000186}
187
Vishesha195ca32020-04-07 18:46:20 +0530188static void set_ext_overrides(AV1_COMMON *const cm,
189 EncodeFrameParams *const frame_params,
190 ExternalFlags *const ext_flags) {
David Turner07dbd8e2019-01-08 17:16:25 +0000191 // Overrides the defaults with the externally supplied values with
192 // av1_update_reference() and av1_update_entropy() calls
193 // Note: The overrides are valid only for the next frame passed
194 // to av1_encode_lowlevel()
195
Vishesha195ca32020-04-07 18:46:20 +0530196 if (ext_flags->use_s_frame) {
David Turner475a3132019-01-18 15:17:17 +0000197 frame_params->frame_type = S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000198 }
David Turner07dbd8e2019-01-08 17:16:25 +0000199
Vishesha195ca32020-04-07 18:46:20 +0530200 if (ext_flags->refresh_frame_context_pending) {
201 cm->features.refresh_frame_context = ext_flags->refresh_frame_context;
202 ext_flags->refresh_frame_context_pending = 0;
David Turner07dbd8e2019-01-08 17:16:25 +0000203 }
Vishesha195ca32020-04-07 18:46:20 +0530204 cm->features.allow_ref_frame_mvs = ext_flags->use_ref_frame_mvs;
David Turner07dbd8e2019-01-08 17:16:25 +0000205
Vishesha195ca32020-04-07 18:46:20 +0530206 frame_params->error_resilient_mode = ext_flags->use_error_resilient;
David Turner07dbd8e2019-01-08 17:16:25 +0000207 // A keyframe is already error resilient and keyframes with
208 // error_resilient_mode interferes with the use of show_existing_frame
209 // when forward reference keyframes are enabled.
David Turner475a3132019-01-18 15:17:17 +0000210 frame_params->error_resilient_mode &= frame_params->frame_type != KEY_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000211 // For bitstream conformance, s-frames must be error-resilient
David Turner475a3132019-01-18 15:17:17 +0000212 frame_params->error_resilient_mode |= frame_params->frame_type == S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000213}
214
David Turnera7f133c2019-01-22 14:47:16 +0000215static int get_current_frame_ref_type(
216 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
David Turnera7f133c2019-01-22 14:47:16 +0000217 // We choose the reference "type" of this frame from the flags which indicate
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700218 // which reference frames will be refreshed by it. More than one of these
219 // flags may be set, so the order here implies an order of precedence. This is
220 // just used to choose the primary_ref_frame (as the most recent reference
221 // buffer of the same reference-type as the current frame)
David Turnera7f133c2019-01-22 14:47:16 +0000222
Jingning Han370d1162019-07-03 10:24:03 -0700223 (void)frame_params;
224 // TODO(jingning): This table should be a lot simpler with the new
225 // ARF system in place. Keep frame_params for the time being as we are
226 // still evaluating a few design options.
Mufaddal Chakera8ee04fa2021-03-17 13:33:18 +0530227 switch (cpi->ppi->gf_group.layer_depth[cpi->gf_frame_index]) {
Jingning Han370d1162019-07-03 10:24:03 -0700228 case 0: return 0;
229 case 1: return 1;
230 case MAX_ARF_LAYERS:
231 case MAX_ARF_LAYERS + 1: return 4;
232 default: return 7;
233 }
David Turnera7f133c2019-01-22 14:47:16 +0000234}
235
236static int choose_primary_ref_frame(
237 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
238 const AV1_COMMON *const cm = &cpi->common;
239
240 const int intra_only = frame_params->frame_type == KEY_FRAME ||
241 frame_params->frame_type == INTRA_ONLY_FRAME;
Marco Paniconiee968342020-06-08 11:21:48 -0700242 if (intra_only || frame_params->error_resilient_mode ||
Vishesha195ca32020-04-07 18:46:20 +0530243 cpi->ext_flags.use_primary_ref_none) {
David Turnera7f133c2019-01-22 14:47:16 +0000244 return PRIMARY_REF_NONE;
245 }
246
Yunqing Wangd0f0d3b2019-12-23 12:15:44 -0800247 // In large scale case, always use Last frame's frame contexts.
248 // Note(yunqing): In other cases, primary_ref_frame is chosen based on
Mufaddal Chakera8ee04fa2021-03-17 13:33:18 +0530249 // cpi->ppi->gf_group.layer_depth[cpi->gf_frame_index], which also controls
Yunqing Wangd0f0d3b2019-12-23 12:15:44 -0800250 // frame bit allocation.
Urvang Joshi54ffae72020-03-23 13:37:10 -0700251 if (cm->tiles.large_scale) return (LAST_FRAME - LAST_FRAME);
Yunqing Wangd0f0d3b2019-12-23 12:15:44 -0800252
Tarundeep Singh15eb4de2021-04-21 15:53:10 +0530253 if (cpi->ppi->use_svc) return av1_svc_primary_ref_frame(cpi);
Marco Paniconi42e1bdd2020-06-10 16:47:39 -0700254
David Turnera7f133c2019-01-22 14:47:16 +0000255 // Find the most recent reference frame with the same reference type as the
256 // current frame
Jingning Han6d878912020-02-28 10:23:35 -0800257 const int current_ref_type = get_current_frame_ref_type(cpi, frame_params);
David Turnera7f133c2019-01-22 14:47:16 +0000258 int wanted_fb = cpi->fb_of_context_type[current_ref_type];
259
260 int primary_ref_frame = PRIMARY_REF_NONE;
261 for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
262 if (get_ref_frame_map_idx(cm, ref_frame) == wanted_fb) {
263 primary_ref_frame = ref_frame - LAST_FRAME;
264 }
265 }
Jingning Han370d1162019-07-03 10:24:03 -0700266
David Turnera7f133c2019-01-22 14:47:16 +0000267 return primary_ref_frame;
268}
269
270static void update_fb_of_context_type(
271 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params,
272 int *const fb_of_context_type) {
273 const AV1_COMMON *const cm = &cpi->common;
Jingning Han370d1162019-07-03 10:24:03 -0700274 const int current_frame_ref_type =
275 get_current_frame_ref_type(cpi, frame_params);
David Turnera7f133c2019-01-22 14:47:16 +0000276
Urvang Joshib6409e92020-03-23 11:23:27 -0700277 if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
Vishesha195ca32020-04-07 18:46:20 +0530278 cpi->ext_flags.use_primary_ref_none) {
David Turnera7f133c2019-01-22 14:47:16 +0000279 for (int i = 0; i < REF_FRAMES; i++) {
280 fb_of_context_type[i] = -1;
281 }
Jingning Han370d1162019-07-03 10:24:03 -0700282 fb_of_context_type[current_frame_ref_type] =
David Turnera7f133c2019-01-22 14:47:16 +0000283 cm->show_frame ? get_ref_frame_map_idx(cm, GOLDEN_FRAME)
284 : get_ref_frame_map_idx(cm, ALTREF_FRAME);
285 }
286
287 if (!encode_show_existing_frame(cm)) {
288 // Refresh fb_of_context_type[]: see encoder.h for explanation
David Turnera7f133c2019-01-22 14:47:16 +0000289 if (cm->current_frame.frame_type == KEY_FRAME) {
290 // All ref frames are refreshed, pick one that will live long enough
Jingning Han370d1162019-07-03 10:24:03 -0700291 fb_of_context_type[current_frame_ref_type] = 0;
David Turnera7f133c2019-01-22 14:47:16 +0000292 } else {
293 // If more than one frame is refreshed, it doesn't matter which one we
294 // pick so pick the first. LST sometimes doesn't refresh any: this is ok
Jingning Han370d1162019-07-03 10:24:03 -0700295
David Turnera7f133c2019-01-22 14:47:16 +0000296 for (int i = 0; i < REF_FRAMES; i++) {
297 if (cm->current_frame.refresh_frame_flags & (1 << i)) {
298 fb_of_context_type[current_frame_ref_type] = i;
299 break;
300 }
301 }
302 }
303 }
304}
305
Deepa K Gfb89ce02020-04-06 13:34:42 +0530306static void adjust_frame_rate(AV1_COMP *cpi, int64_t ts_start, int64_t ts_end) {
307 TimeStamps *time_stamps = &cpi->time_stamps;
David Turnerdedd8ff2019-01-23 13:59:46 +0000308 int64_t this_duration;
309 int step = 0;
310
311 // Clear down mmx registers
312 aom_clear_system_state();
313
Tarundeep Singh15eb4de2021-04-21 15:53:10 +0530314 if (cpi->ppi->use_svc && cpi->svc.spatial_layer_id > 0) {
Marco Paniconi63971322019-08-15 21:32:05 -0700315 cpi->framerate = cpi->svc.base_framerate;
316 av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
317 return;
318 }
319
Yunqing Wang15ab03c2020-11-24 16:45:25 -0800320 if (ts_start == time_stamps->first_ts_start) {
Deepa K Gfb89ce02020-04-06 13:34:42 +0530321 this_duration = ts_end - ts_start;
David Turnerdedd8ff2019-01-23 13:59:46 +0000322 step = 1;
323 } else {
324 int64_t last_duration =
Yunqing Wang15ab03c2020-11-24 16:45:25 -0800325 time_stamps->prev_ts_end - time_stamps->prev_ts_start;
David Turnerdedd8ff2019-01-23 13:59:46 +0000326
Yunqing Wang15ab03c2020-11-24 16:45:25 -0800327 this_duration = ts_end - time_stamps->prev_ts_end;
David Turnerdedd8ff2019-01-23 13:59:46 +0000328
329 // do a step update if the duration changes by 10%
330 if (last_duration)
331 step = (int)((this_duration - last_duration) * 10 / last_duration);
332 }
333
334 if (this_duration) {
335 if (step) {
336 av1_new_framerate(cpi, 10000000.0 / this_duration);
337 } else {
338 // Average this frame's rate into the last second's average
339 // frame rate. If we haven't seen 1 second yet, then average
340 // over the whole interval seen.
Deepa K Gfb89ce02020-04-06 13:34:42 +0530341 const double interval =
Yunqing Wang15ab03c2020-11-24 16:45:25 -0800342 AOMMIN((double)(ts_end - time_stamps->first_ts_start), 10000000.0);
David Turnerdedd8ff2019-01-23 13:59:46 +0000343 double avg_duration = 10000000.0 / cpi->framerate;
344 avg_duration *= (interval - avg_duration + this_duration);
345 avg_duration /= interval;
346
347 av1_new_framerate(cpi, 10000000.0 / avg_duration);
348 }
349 }
Yunqing Wang15ab03c2020-11-24 16:45:25 -0800350 time_stamps->prev_ts_start = ts_start;
351 time_stamps->prev_ts_end = ts_end;
David Turnerdedd8ff2019-01-23 13:59:46 +0000352}
353
David Turnerdedd8ff2019-01-23 13:59:46 +0000354// Determine whether there is a forced keyframe pending in the lookahead buffer
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530355int is_forced_keyframe_pending(struct lookahead_ctx *lookahead,
356 const int up_to_index,
357 const COMPRESSOR_STAGE compressor_stage) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000358 for (int i = 0; i <= up_to_index; i++) {
Mufaddal Chakera73b7b702019-12-09 11:44:55 +0530359 const struct lookahead_entry *e =
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530360 av1_lookahead_peek(lookahead, i, compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000361 if (e == NULL) {
362 // We have reached the end of the lookahead buffer and not early-returned
363 // so there isn't a forced key-frame pending.
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530364 return -1;
David Turnerdedd8ff2019-01-23 13:59:46 +0000365 } else if (e->flags == AOM_EFLAG_FORCE_KF) {
Aasaipriya592cb002020-12-14 19:24:24 +0530366 return i;
David Turnerdedd8ff2019-01-23 13:59:46 +0000367 } else {
368 continue;
369 }
370 }
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530371 return -1; // Never reached
David Turnerdedd8ff2019-01-23 13:59:46 +0000372}
373
Urvang Joshif70375a2019-03-22 23:30:19 -0700374// Check if we should encode an ARF or internal ARF. If not, try a LAST
David Turnerdedd8ff2019-01-23 13:59:46 +0000375// Do some setup associated with the chosen source
David Turner4f1f1812019-01-24 17:00:24 +0000376// temporal_filtered, flush, and frame_update_type are outputs.
David Turnerdedd8ff2019-01-23 13:59:46 +0000377// Return the frame source, or NULL if we couldn't find one
Yaowu Xufac3d862019-04-26 15:43:03 -0700378static struct lookahead_entry *choose_frame_source(
Angie Chiang470d1162020-12-31 13:10:55 -0800379 AV1_COMP *const cpi, int *const flush, int *pop_lookahead,
380 struct lookahead_entry **last_source,
bohanli0db9c512020-06-12 17:43:06 -0700381 EncodeFrameParams *const frame_params) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000382 AV1_COMMON *const cm = &cpi->common;
Mufaddal Chakera8ee04fa2021-03-17 13:33:18 +0530383 const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
David Turnerdedd8ff2019-01-23 13:59:46 +0000384 struct lookahead_entry *source = NULL;
David Turnerdedd8ff2019-01-23 13:59:46 +0000385
bohanli0db9c512020-06-12 17:43:06 -0700386 // Source index in lookahead buffer.
Mufaddal Chakeraab20d372021-03-17 12:18:34 +0530387 int src_index = gf_group->arf_src_offset[cpi->gf_frame_index];
bohanli0db9c512020-06-12 17:43:06 -0700388
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530389 // TODO(Aasaipriya): Forced key frames need to be fixed when rc_mode != AOM_Q
bohanli0db9c512020-06-12 17:43:06 -0700390 if (src_index &&
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +0530391 (is_forced_keyframe_pending(cpi->ppi->lookahead, src_index,
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530392 cpi->compressor_stage) != -1) &&
Mufaddal Chakera186f8e32021-03-17 13:20:00 +0530393 cpi->oxcf.rc_cfg.mode != AOM_Q && !is_stat_generation_stage(cpi)) {
bohanli0db9c512020-06-12 17:43:06 -0700394 src_index = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000395 *flush = 1;
396 }
397
bohanli0db9c512020-06-12 17:43:06 -0700398 // If the current frame is arf, then we should not pop from the lookahead
399 // buffer. If the current frame is not arf, then pop it. This assumes the
400 // first frame in the GF group is not arf. May need to change if it is not
401 // true.
Angie Chiang470d1162020-12-31 13:10:55 -0800402 *pop_lookahead = (src_index == 0);
bohanli1478d862020-06-17 20:53:44 -0700403 // If this is a key frame and keyframe filtering is enabled with overlay,
404 // then do not pop.
Angie Chiang470d1162020-12-31 13:10:55 -0800405 if (*pop_lookahead && cpi->oxcf.kf_cfg.enable_keyframe_filtering > 1 &&
Mufaddal Chakeraab20d372021-03-17 12:18:34 +0530406 gf_group->update_type[cpi->gf_frame_index] == ARF_UPDATE &&
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +0530407 !is_stat_generation_stage(cpi) && cpi->ppi->lookahead) {
408 if (cpi->ppi->lookahead->read_ctxs[cpi->compressor_stage].sz &&
bohanli1478d862020-06-17 20:53:44 -0700409 (*flush ||
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +0530410 cpi->ppi->lookahead->read_ctxs[cpi->compressor_stage].sz ==
411 cpi->ppi->lookahead->read_ctxs[cpi->compressor_stage].pop_sz)) {
Angie Chiang470d1162020-12-31 13:10:55 -0800412 *pop_lookahead = 0;
bohanli1478d862020-06-17 20:53:44 -0700413 }
414 }
Mufaddal Chakera186f8e32021-03-17 13:20:00 +0530415
416 // LAP stage does not have ARFs or forward key-frames,
417 // hence, always pop_lookahead here.
418 if (is_stat_generation_stage(cpi)) {
419 *pop_lookahead = 1;
420 }
421
Angie Chiang470d1162020-12-31 13:10:55 -0800422 frame_params->show_frame = *pop_lookahead;
423 if (*pop_lookahead) {
bohanli0db9c512020-06-12 17:43:06 -0700424 // show frame, pop from buffer
David Turnerdedd8ff2019-01-23 13:59:46 +0000425 // Get last frame source.
426 if (cm->current_frame.frame_number > 0) {
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530427 *last_source =
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +0530428 av1_lookahead_peek(cpi->ppi->lookahead, -1, cpi->compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000429 }
430 // Read in the source frame.
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +0530431 source = av1_lookahead_peek(cpi->ppi->lookahead, 0, cpi->compressor_stage);
bohanli0db9c512020-06-12 17:43:06 -0700432 } else {
433 // no show frames are arf frames
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +0530434 source = av1_lookahead_peek(cpi->ppi->lookahead, src_index,
435 cpi->compressor_stage);
bohanli0db9c512020-06-12 17:43:06 -0700436 // When src_index == rc->frames_to_key, it indicates a fwd_kf
bohanli6f22c7a2020-07-14 10:52:50 -0700437 if (src_index == cpi->rc.frames_to_key && src_index != 0) {
438 cpi->no_show_fwd_kf = 1;
bohanli0db9c512020-06-12 17:43:06 -0700439 }
440 if (source != NULL) {
441 cm->showable_frame = 1;
442 }
David Turnerdedd8ff2019-01-23 13:59:46 +0000443 }
444 return source;
445}
446
David Turnerb0c0aa32019-01-28 16:17:13 +0000447// Don't allow a show_existing_frame to coincide with an error resilient or
448// S-Frame. An exception can be made in the case of a keyframe, since it does
449// not depend on any previous frames.
David Turner73245762019-02-11 16:42:34 +0000450static int allow_show_existing(const AV1_COMP *const cpi,
451 unsigned int frame_flags) {
David Turnerb0c0aa32019-01-28 16:17:13 +0000452 if (cpi->common.current_frame.frame_number == 0) return 0;
453
454 const struct lookahead_entry *lookahead_src =
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +0530455 av1_lookahead_peek(cpi->ppi->lookahead, 0, cpi->compressor_stage);
David Turnerb0c0aa32019-01-28 16:17:13 +0000456 if (lookahead_src == NULL) return 1;
457
458 const int is_error_resilient =
Visheshaa6a1702020-06-30 19:27:22 +0530459 cpi->oxcf.tool_cfg.error_resilient_mode ||
David Turnerb0c0aa32019-01-28 16:17:13 +0000460 (lookahead_src->flags & AOM_EFLAG_ERROR_RESILIENT);
Vishesh7e9873d2020-06-08 15:41:33 +0530461 const int is_s_frame = cpi->oxcf.kf_cfg.enable_sframe ||
462 (lookahead_src->flags & AOM_EFLAG_SET_S_FRAME);
David Turnerb0c0aa32019-01-28 16:17:13 +0000463 const int is_key_frame =
David Turner73245762019-02-11 16:42:34 +0000464 (cpi->rc.frames_to_key == 0) || (frame_flags & FRAMEFLAGS_KEY);
David Turnerb0c0aa32019-01-28 16:17:13 +0000465 return !(is_error_resilient || is_s_frame) || is_key_frame;
466}
467
David Turner73245762019-02-11 16:42:34 +0000468// Update frame_flags to tell the encoder's caller what sort of frame was
469// encoded.
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530470static void update_frame_flags(
471 const AV1_COMMON *const cm,
472 const RefreshFrameFlagsInfo *const refresh_frame_flags,
473 unsigned int *frame_flags) {
474 if (encode_show_existing_frame(cm)) {
David Turner73245762019-02-11 16:42:34 +0000475 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
476 *frame_flags &= ~FRAMEFLAGS_BWDREF;
477 *frame_flags &= ~FRAMEFLAGS_ALTREF;
478 *frame_flags &= ~FRAMEFLAGS_KEY;
479 return;
480 }
481
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530482 if (refresh_frame_flags->golden_frame) {
David Turner73245762019-02-11 16:42:34 +0000483 *frame_flags |= FRAMEFLAGS_GOLDEN;
484 } else {
485 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
486 }
487
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530488 if (refresh_frame_flags->alt_ref_frame) {
David Turner73245762019-02-11 16:42:34 +0000489 *frame_flags |= FRAMEFLAGS_ALTREF;
490 } else {
491 *frame_flags &= ~FRAMEFLAGS_ALTREF;
492 }
493
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530494 if (refresh_frame_flags->bwd_ref_frame) {
David Turner73245762019-02-11 16:42:34 +0000495 *frame_flags |= FRAMEFLAGS_BWDREF;
496 } else {
497 *frame_flags &= ~FRAMEFLAGS_BWDREF;
498 }
499
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530500 if (cm->current_frame.frame_type == KEY_FRAME) {
David Turner73245762019-02-11 16:42:34 +0000501 *frame_flags |= FRAMEFLAGS_KEY;
502 } else {
503 *frame_flags &= ~FRAMEFLAGS_KEY;
504 }
505}
506
507#define DUMP_REF_FRAME_IMAGES 0
508
509#if DUMP_REF_FRAME_IMAGES == 1
510static int dump_one_image(AV1_COMMON *cm,
511 const YV12_BUFFER_CONFIG *const ref_buf,
512 char *file_name) {
513 int h;
514 FILE *f_ref = NULL;
515
516 if (ref_buf == NULL) {
517 printf("Frame data buffer is NULL.\n");
518 return AOM_CODEC_MEM_ERROR;
519 }
520
521 if ((f_ref = fopen(file_name, "wb")) == NULL) {
522 printf("Unable to open file %s to write.\n", file_name);
523 return AOM_CODEC_MEM_ERROR;
524 }
525
526 // --- Y ---
527 for (h = 0; h < cm->height; ++h) {
528 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
529 }
530 // --- U ---
531 for (h = 0; h < (cm->height >> 1); ++h) {
532 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
533 f_ref);
534 }
535 // --- V ---
536 for (h = 0; h < (cm->height >> 1); ++h) {
537 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
538 f_ref);
539 }
540
541 fclose(f_ref);
542
543 return AOM_CODEC_OK;
544}
545
546static void dump_ref_frame_images(AV1_COMP *cpi) {
547 AV1_COMMON *const cm = &cpi->common;
548 MV_REFERENCE_FRAME ref_frame;
549
550 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
551 char file_name[256] = "";
552 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
553 cm->current_frame.frame_number, ref_frame);
554 dump_one_image(cm, get_ref_frame_yv12_buf(cpi, ref_frame), file_name);
555 }
556}
557#endif // DUMP_REF_FRAME_IMAGES == 1
558
Jingning Han81d6fbb2019-07-15 10:14:13 -0700559int av1_get_refresh_ref_frame_map(int refresh_frame_flags) {
Jingning Han8a6a1b82020-08-11 23:46:15 -0700560 int ref_map_index;
Jingning Hanf58175c2019-07-07 15:02:00 -0700561
562 for (ref_map_index = 0; ref_map_index < REF_FRAMES; ++ref_map_index)
563 if ((refresh_frame_flags >> ref_map_index) & 1) break;
564
Jingning Han8a6a1b82020-08-11 23:46:15 -0700565 if (ref_map_index == REF_FRAMES) ref_map_index = INVALID_IDX;
Jingning Hanf58175c2019-07-07 15:02:00 -0700566 return ref_map_index;
567}
568
Jingning Han4711eb12019-08-01 09:56:59 -0700569static void update_arf_stack(int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700570 RefBufferStack *ref_buffer_stack) {
Jingning Han42266ca2019-07-12 14:37:16 -0700571 if (ref_buffer_stack->arf_stack_size >= 0) {
572 if (ref_buffer_stack->arf_stack[0] == ref_map_index)
573 stack_pop(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size);
Jingning Hanf58175c2019-07-07 15:02:00 -0700574 }
575
Jingning Han42266ca2019-07-12 14:37:16 -0700576 if (ref_buffer_stack->lst_stack_size) {
577 for (int i = ref_buffer_stack->lst_stack_size - 1; i >= 0; --i) {
578 if (ref_buffer_stack->lst_stack[i] == ref_map_index) {
579 for (int idx = i; idx < ref_buffer_stack->lst_stack_size - 1; ++idx)
580 ref_buffer_stack->lst_stack[idx] =
581 ref_buffer_stack->lst_stack[idx + 1];
Cheng Chenc86d2bf2019-09-05 15:07:47 -0700582 ref_buffer_stack->lst_stack[ref_buffer_stack->lst_stack_size - 1] =
583 INVALID_IDX;
Jingning Han42266ca2019-07-12 14:37:16 -0700584 --ref_buffer_stack->lst_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700585 }
586 }
587 }
588
Jingning Han42266ca2019-07-12 14:37:16 -0700589 if (ref_buffer_stack->gld_stack_size) {
590 for (int i = ref_buffer_stack->gld_stack_size - 1; i >= 0; --i) {
591 if (ref_buffer_stack->gld_stack[i] == ref_map_index) {
592 for (int idx = i; idx < ref_buffer_stack->gld_stack_size - 1; ++idx)
593 ref_buffer_stack->gld_stack[idx] =
594 ref_buffer_stack->gld_stack[idx + 1];
Cheng Chenc86d2bf2019-09-05 15:07:47 -0700595 ref_buffer_stack->gld_stack[ref_buffer_stack->gld_stack_size - 1] =
596 INVALID_IDX;
Jingning Han42266ca2019-07-12 14:37:16 -0700597 --ref_buffer_stack->gld_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700598 }
599 }
600 }
601}
602
Jingning Han647f2d12019-07-23 14:15:42 -0700603// Update reference frame stack info.
Jingning Han42266ca2019-07-12 14:37:16 -0700604void av1_update_ref_frame_map(AV1_COMP *cpi,
605 FRAME_UPDATE_TYPE frame_update_type,
bohanli99852502020-07-14 16:22:45 -0700606 FRAME_TYPE frame_type, int show_existing_frame,
607 int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700608 RefBufferStack *ref_buffer_stack) {
David Turner73245762019-02-11 16:42:34 +0000609 AV1_COMMON *const cm = &cpi->common;
Jingning Han47aaf872019-07-21 14:56:32 -0700610 // TODO(jingning): Consider the S-frame same as key frame for the
611 // reference frame tracking purpose. The logic might be better
612 // expressed than converting the frame update type.
613 if (frame_is_sframe(cm)) frame_update_type = KEY_FRAME;
614
Vishesh38c05d72020-04-14 12:19:14 +0530615 if (is_frame_droppable(&cpi->svc, &cpi->ext_flags.refresh_frame)) return;
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700616
Jingning Han81d6fbb2019-07-15 10:14:13 -0700617 switch (frame_update_type) {
618 case KEY_FRAME:
Sarah Parkeredffc652019-10-25 16:30:32 -0700619 if (show_existing_frame)
620 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
621 &ref_buffer_stack->arf_stack_size);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700622 stack_reset(ref_buffer_stack->lst_stack,
623 &ref_buffer_stack->lst_stack_size);
624 stack_reset(ref_buffer_stack->gld_stack,
625 &ref_buffer_stack->gld_stack_size);
626 stack_reset(ref_buffer_stack->arf_stack,
627 &ref_buffer_stack->arf_stack_size);
628 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
629 ref_map_index);
630 break;
631 case GF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700632 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700633 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
634 ref_map_index);
Fyodor Kyslov915b9b82019-11-11 11:53:03 -0800635 // For nonrd_mode: update LAST as well on GF_UPDATE frame.
chiyotsai56681b52019-12-16 11:15:25 -0800636 if (cpi->sf.rt_sf.use_nonrd_pick_mode)
Marco Paniconifa29e162019-08-05 18:08:04 -0700637 stack_push(ref_buffer_stack->lst_stack,
638 &ref_buffer_stack->lst_stack_size, ref_map_index);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700639 break;
640 case LF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700641 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700642 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
643 ref_map_index);
644 break;
645 case ARF_UPDATE:
646 case INTNL_ARF_UPDATE:
bohanli99852502020-07-14 16:22:45 -0700647 if (frame_type == KEY_FRAME && !cpi->no_show_fwd_kf) {
648 stack_reset(ref_buffer_stack->lst_stack,
649 &ref_buffer_stack->lst_stack_size);
650 stack_reset(ref_buffer_stack->gld_stack,
651 &ref_buffer_stack->gld_stack_size);
652 stack_reset(ref_buffer_stack->arf_stack,
653 &ref_buffer_stack->arf_stack_size);
654 } else {
655 update_arf_stack(ref_map_index, ref_buffer_stack);
656 }
Jingning Han81d6fbb2019-07-15 10:14:13 -0700657 stack_push(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size,
658 ref_map_index);
659 break;
660 case OVERLAY_UPDATE:
bohanli2541b8a2020-10-14 17:33:13 -0700661 if (frame_type == KEY_FRAME) {
662 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
663 &ref_buffer_stack->arf_stack_size);
664 stack_reset(ref_buffer_stack->lst_stack,
665 &ref_buffer_stack->lst_stack_size);
666 stack_reset(ref_buffer_stack->gld_stack,
667 &ref_buffer_stack->gld_stack_size);
668 stack_reset(ref_buffer_stack->arf_stack,
669 &ref_buffer_stack->arf_stack_size);
670 stack_push(ref_buffer_stack->gld_stack,
671 &ref_buffer_stack->gld_stack_size, ref_map_index);
672 } else {
673 if (ref_map_index != INVALID_IDX) {
674 update_arf_stack(ref_map_index, ref_buffer_stack);
675 stack_push(ref_buffer_stack->lst_stack,
676 &ref_buffer_stack->lst_stack_size, ref_map_index);
677 }
678 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
679 &ref_buffer_stack->arf_stack_size);
680 stack_push(ref_buffer_stack->gld_stack,
681 &ref_buffer_stack->gld_stack_size, ref_map_index);
Jingning Han1a7fbd72020-09-25 13:30:06 -0700682 }
Jingning Han81d6fbb2019-07-15 10:14:13 -0700683 break;
684 case INTNL_OVERLAY_UPDATE:
685 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
686 &ref_buffer_stack->arf_stack_size);
687 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
688 ref_map_index);
689 break;
690 default: assert(0 && "unknown type");
Jingning Hancf6d3252019-07-03 14:26:45 -0700691 }
Jingning Han84a70502019-07-19 11:38:14 -0700692 return;
David Turner73245762019-02-11 16:42:34 +0000693}
694
Jingning Han42266ca2019-07-12 14:37:16 -0700695static int get_free_ref_map_index(const RefBufferStack *ref_buffer_stack) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700696 for (int idx = 0; idx < REF_FRAMES; ++idx) {
697 int is_free = 1;
Jingning Han42266ca2019-07-12 14:37:16 -0700698 for (int i = 0; i < ref_buffer_stack->arf_stack_size; ++i) {
699 if (ref_buffer_stack->arf_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700700 is_free = 0;
701 break;
702 }
703 }
704
Jingning Han42266ca2019-07-12 14:37:16 -0700705 for (int i = 0; i < ref_buffer_stack->lst_stack_size; ++i) {
706 if (ref_buffer_stack->lst_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700707 is_free = 0;
708 break;
709 }
710 }
711
Jingning Han42266ca2019-07-12 14:37:16 -0700712 for (int i = 0; i < ref_buffer_stack->gld_stack_size; ++i) {
713 if (ref_buffer_stack->gld_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700714 is_free = 0;
715 break;
716 }
717 }
718
719 if (is_free) return idx;
720 }
721 return INVALID_IDX;
722}
723
Jingning Han42266ca2019-07-12 14:37:16 -0700724int av1_get_refresh_frame_flags(const AV1_COMP *const cpi,
725 const EncodeFrameParams *const frame_params,
726 FRAME_UPDATE_TYPE frame_update_type,
727 const RefBufferStack *const ref_buffer_stack) {
David Turner6e8b4d92019-02-18 15:01:33 +0000728 const AV1_COMMON *const cm = &cpi->common;
Vishesh38c05d72020-04-14 12:19:14 +0530729 const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
730 &cpi->ext_flags.refresh_frame;
731
Vishesha195ca32020-04-07 18:46:20 +0530732 const SVC *const svc = &cpi->svc;
David Turner6e8b4d92019-02-18 15:01:33 +0000733 // Switch frames and shown key-frames overwrite all reference slots
bohanli6f22c7a2020-07-14 10:52:50 -0700734 if ((frame_params->frame_type == KEY_FRAME && !cpi->no_show_fwd_kf) ||
David Turner6e8b4d92019-02-18 15:01:33 +0000735 frame_params->frame_type == S_FRAME)
736 return 0xFF;
737
738 // show_existing_frames don't actually send refresh_frame_flags so set the
739 // flags to 0 to keep things consistent.
David Turnere86ee0d2019-02-18 17:16:28 +0000740 if (frame_params->show_existing_frame &&
741 (!frame_params->error_resilient_mode ||
742 frame_params->frame_type == KEY_FRAME)) {
David Turner6e8b4d92019-02-18 15:01:33 +0000743 return 0;
744 }
745
Vishesh38c05d72020-04-14 12:19:14 +0530746 if (is_frame_droppable(svc, ext_refresh_frame_flags)) return 0;
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700747
David Turner6e8b4d92019-02-18 15:01:33 +0000748 int refresh_mask = 0;
749
Vishesh38c05d72020-04-14 12:19:14 +0530750 if (ext_refresh_frame_flags->update_pending) {
Marco Paniconie5de3322021-03-22 22:03:17 -0700751 if (svc->set_ref_frame_config) {
Marco Paniconid8574e32019-08-04 21:30:12 -0700752 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
Vishesha195ca32020-04-07 18:46:20 +0530753 int ref_frame_map_idx = svc->ref_idx[i];
754 refresh_mask |= svc->refresh[ref_frame_map_idx] << ref_frame_map_idx;
Marco Paniconid8574e32019-08-04 21:30:12 -0700755 }
756 return refresh_mask;
757 }
David Turner6e8b4d92019-02-18 15:01:33 +0000758 // Unfortunately the encoder interface reflects the old refresh_*_frame
759 // flags so we have to replicate the old refresh_frame_flags logic here in
760 // order to preserve the behaviour of the flag overrides.
Marco Paniconi314bc362019-08-13 10:53:02 -0700761 int ref_frame_map_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
Jingning Han0a2af4e2019-07-08 19:30:03 -0700762 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530763 refresh_mask |= ext_refresh_frame_flags->last_frame << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700764
765 ref_frame_map_idx = get_ref_frame_map_idx(cm, EXTREF_FRAME);
766 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530767 refresh_mask |= ext_refresh_frame_flags->bwd_ref_frame
768 << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700769
770 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF2_FRAME);
771 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530772 refresh_mask |= ext_refresh_frame_flags->alt2_ref_frame
773 << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700774
David Turner6e8b4d92019-02-18 15:01:33 +0000775 if (frame_update_type == OVERLAY_UPDATE) {
Jingning Han5738e032019-07-22 15:22:52 -0700776 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
777 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530778 refresh_mask |= ext_refresh_frame_flags->golden_frame
779 << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000780 } else {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700781 ref_frame_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
782 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530783 refresh_mask |= ext_refresh_frame_flags->golden_frame
784 << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700785
786 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
787 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530788 refresh_mask |= ext_refresh_frame_flags->alt_ref_frame
789 << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000790 }
791 return refresh_mask;
792 }
793
Jingning Hanc9c172d2019-07-23 14:10:32 -0700794 // Search for the open slot to store the current frame.
Jingning Han81d6fbb2019-07-15 10:14:13 -0700795 int free_fb_index = get_free_ref_map_index(ref_buffer_stack);
Jingning Han0a2af4e2019-07-08 19:30:03 -0700796 switch (frame_update_type) {
797 case KF_UPDATE:
798 case GF_UPDATE:
799 if (free_fb_index != INVALID_IDX) {
800 refresh_mask = 1 << free_fb_index;
801 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700802 if (ref_buffer_stack->gld_stack_size)
803 refresh_mask =
804 1 << ref_buffer_stack
805 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700806 else
Jingning Han42266ca2019-07-12 14:37:16 -0700807 refresh_mask =
808 1 << ref_buffer_stack
809 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700810 }
811 break;
812 case LF_UPDATE:
813 if (free_fb_index != INVALID_IDX) {
814 refresh_mask = 1 << free_fb_index;
815 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700816 if (ref_buffer_stack->lst_stack_size >= 2)
817 refresh_mask =
818 1 << ref_buffer_stack
819 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han1af1c012020-02-10 10:51:56 -0800820 else if (ref_buffer_stack->gld_stack_size >= 2)
821 refresh_mask =
822 1 << ref_buffer_stack
823 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700824 else
825 assert(0 && "No ref map index found");
826 }
827 break;
828 case ARF_UPDATE:
829 if (free_fb_index != INVALID_IDX) {
830 refresh_mask = 1 << free_fb_index;
831 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700832 if (ref_buffer_stack->gld_stack_size >= 3)
833 refresh_mask =
834 1 << ref_buffer_stack
835 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
836 else if (ref_buffer_stack->lst_stack_size >= 2)
837 refresh_mask =
838 1 << ref_buffer_stack
839 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700840 else
841 assert(0 && "No ref map index found");
842 }
843 break;
844 case INTNL_ARF_UPDATE:
845 if (free_fb_index != INVALID_IDX) {
846 refresh_mask = 1 << free_fb_index;
847 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700848 refresh_mask =
849 1 << ref_buffer_stack
850 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700851 }
852 break;
Jingning Han1a7fbd72020-09-25 13:30:06 -0700853 case OVERLAY_UPDATE:
854 if (free_fb_index != INVALID_IDX) refresh_mask = 1 << free_fb_index;
855 break;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700856 case INTNL_OVERLAY_UPDATE: break;
857 default: assert(0); break;
858 }
859
860 return refresh_mask;
David Turner6e8b4d92019-02-18 15:01:33 +0000861}
862
Cheng Chen7abe3132019-06-19 11:55:28 -0700863#if !CONFIG_REALTIME_ONLY
Cheng Chen5083a9f2019-07-12 15:33:34 -0700864void setup_mi(AV1_COMP *const cpi, YV12_BUFFER_CONFIG *src) {
865 AV1_COMMON *const cm = &cpi->common;
866 const int num_planes = av1_num_planes(cm);
867 MACROBLOCK *const x = &cpi->td.mb;
868 MACROBLOCKD *const xd = &x->e_mbd;
869
Tarundeep Singh4243e622021-04-20 16:10:22 +0530870 av1_setup_src_planes(x, src, 0, 0, num_planes, cm->seq_params->sb_size);
Cheng Chen5083a9f2019-07-12 15:33:34 -0700871
Tarundeep Singh4243e622021-04-20 16:10:22 +0530872 av1_setup_block_planes(xd, cm->seq_params->subsampling_x,
873 cm->seq_params->subsampling_y, num_planes);
Cheng Chen5083a9f2019-07-12 15:33:34 -0700874
Urvang Joshi2603bfe2020-03-25 13:33:18 -0700875 set_mi_offsets(&cm->mi_params, xd, 0, 0);
Cheng Chen5083a9f2019-07-12 15:33:34 -0700876}
877
bohanli0db9c512020-06-12 17:43:06 -0700878// Apply temporal filtering to source frames and encode the filtered frame.
879// If the current frame does not require filtering, this function is identical
880// to av1_encode() except that tpl is not performed.
Cheng Chen7abe3132019-06-19 11:55:28 -0700881static int denoise_and_encode(AV1_COMP *const cpi, uint8_t *const dest,
882 EncodeFrameInput *const frame_input,
883 EncodeFrameParams *const frame_params,
Hui Su028ad7d2020-04-13 23:24:32 -0700884 EncodeFrameResults *const frame_results) {
Yunqing Wang7a3ad542020-11-03 23:40:24 -0800885#if CONFIG_COLLECT_COMPONENT_TIMING
886 if (cpi->oxcf.pass == 2) start_timing(cpi, denoise_and_encode_time);
887#endif
Cheng Chen7abe3132019-06-19 11:55:28 -0700888 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
889 AV1_COMMON *const cm = &cpi->common;
Mufaddal Chakera8ee04fa2021-03-17 13:33:18 +0530890 const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
Mufaddal Chakeraab20d372021-03-17 12:18:34 +0530891 FRAME_UPDATE_TYPE update_type =
Mufaddal Chakera8ee04fa2021-03-17 13:33:18 +0530892 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
Jingning Han97b64a72019-10-08 11:40:51 -0700893
Hui Su028ad7d2020-04-13 23:24:32 -0700894 // Decide whether to apply temporal filtering to the source frame.
bohanli0db9c512020-06-12 17:43:06 -0700895 int apply_filtering = 0;
bohanli0db9c512020-06-12 17:43:06 -0700896 if (frame_params->frame_type == KEY_FRAME) {
897 // Decide whether it is allowed to perform key frame filtering
898 int allow_kf_filtering =
899 oxcf->kf_cfg.enable_keyframe_filtering &&
900 !is_stat_generation_stage(cpi) && !frame_params->show_existing_frame &&
901 cpi->rc.frames_to_key > cpi->oxcf.algo_cfg.arnr_max_frames &&
902 !is_lossless_requested(&oxcf->rc_cfg) &&
Jayasanker J90aa0df2021-01-27 13:03:13 +0530903 oxcf->algo_cfg.arnr_max_frames > 0 && oxcf->gf_cfg.lag_in_frames > 1;
bohanli0db9c512020-06-12 17:43:06 -0700904 if (allow_kf_filtering) {
905 const double y_noise_level = av1_estimate_noise_from_single_plane(
Tarundeep Singh4243e622021-04-20 16:10:22 +0530906 frame_input->source, 0, cm->seq_params->bit_depth);
bohanli0db9c512020-06-12 17:43:06 -0700907 apply_filtering = y_noise_level > 0;
Sarah Parker21f1e6e2019-11-15 16:48:29 -0800908 } else {
bohanli0db9c512020-06-12 17:43:06 -0700909 apply_filtering = 0;
Sarah Parker21f1e6e2019-11-15 16:48:29 -0800910 }
bohanli0db9c512020-06-12 17:43:06 -0700911 // If we are doing kf filtering, set up a few things.
912 if (apply_filtering) {
bohanli0db9c512020-06-12 17:43:06 -0700913 av1_setup_past_independence(cm);
bohanli0db9c512020-06-12 17:43:06 -0700914 }
Angie Chiang7b0628b2021-01-10 18:07:49 -0800915 } else if (update_type == ARF_UPDATE || update_type == INTNL_ARF_UPDATE) {
bohanli0db9c512020-06-12 17:43:06 -0700916 // ARF
917 apply_filtering = oxcf->algo_cfg.arnr_max_frames > 0;
bohanli0db9c512020-06-12 17:43:06 -0700918 }
Mufaddal Chakera186f8e32021-03-17 13:20:00 +0530919 if (is_stat_generation_stage(cpi)) {
920 apply_filtering = 0;
921 }
Yunqing Wang7a3ad542020-11-03 23:40:24 -0800922
923#if CONFIG_COLLECT_COMPONENT_TIMING
924 if (cpi->oxcf.pass == 2) start_timing(cpi, apply_filtering_time);
925#endif
bohanli0db9c512020-06-12 17:43:06 -0700926 // Save the pointer to the original source image.
927 YV12_BUFFER_CONFIG *source_buffer = frame_input->source;
928 // apply filtering to frame
929 if (apply_filtering) {
930 int show_existing_alt_ref = 0;
931 // TODO(bohanli): figure out why we need frame_type in cm here.
932 cm->current_frame.frame_type = frame_params->frame_type;
Mufaddal Chakeraab20d372021-03-17 12:18:34 +0530933 int arf_src_index = gf_group->arf_src_offset[cpi->gf_frame_index];
Angie Chiang7b0628b2021-01-10 18:07:49 -0800934 int is_forward_keyframe = 0;
Angie Chiang470d1162020-12-31 13:10:55 -0800935 if (!frame_params->show_frame && cpi->no_show_fwd_kf) {
Angie Chiang7b0628b2021-01-10 18:07:49 -0800936 // TODO(angiebird): Figure out why this condition yields forward keyframe.
Angie Chiang470d1162020-12-31 13:10:55 -0800937 // fwd kf
Angie Chiang7b0628b2021-01-10 18:07:49 -0800938 is_forward_keyframe = 1;
Angie Chiang470d1162020-12-31 13:10:55 -0800939 }
bohanli0db9c512020-06-12 17:43:06 -0700940 const int code_arf =
Angie Chiang7b0628b2021-01-10 18:07:49 -0800941 av1_temporal_filter(cpi, arf_src_index, update_type,
942 is_forward_keyframe, &show_existing_alt_ref);
bohanli0db9c512020-06-12 17:43:06 -0700943 if (code_arf) {
Tarundeep Singh4593fcf2021-03-31 00:53:31 +0530944 aom_extend_frame_borders(&cpi->ppi->alt_ref_buffer, av1_num_planes(cm));
945 frame_input->source = &cpi->ppi->alt_ref_buffer;
Daniel Max Valenzuelacab4d392020-07-10 15:28:11 -0700946 aom_copy_metadata_to_frame_buffer(frame_input->source,
947 source_buffer->metadata);
bohanli0db9c512020-06-12 17:43:06 -0700948 }
bohanlicbe8e742020-08-17 14:19:17 -0700949 // Currently INTNL_ARF_UPDATE only do show_existing.
Angie Chiang7b0628b2021-01-10 18:07:49 -0800950 if (update_type == ARF_UPDATE && !cpi->no_show_fwd_kf) {
bohanli0db9c512020-06-12 17:43:06 -0700951 cpi->show_existing_alt_ref = show_existing_alt_ref;
952 }
Hui Sub1485372020-04-16 23:31:39 -0700953 }
Yunqing Wang7a3ad542020-11-03 23:40:24 -0800954#if CONFIG_COLLECT_COMPONENT_TIMING
955 if (cpi->oxcf.pass == 2) end_timing(cpi, apply_filtering_time);
956#endif
Jingning Han97b64a72019-10-08 11:40:51 -0700957
bohanli0db9c512020-06-12 17:43:06 -0700958 // perform tpl after filtering
Deepa K G23d914b2020-07-08 14:04:13 +0530959 int allow_tpl = oxcf->gf_cfg.lag_in_frames > 1 &&
bohanli0db9c512020-06-12 17:43:06 -0700960 !is_stat_generation_stage(cpi) &&
961 oxcf->algo_cfg.enable_tpl_model;
962 if (frame_params->frame_type == KEY_FRAME) {
Bohan Li8e6d8b22021-01-14 14:57:15 -0800963 // Don't do tpl for fwd key frames or fwd key frame overlays
bohanli0db9c512020-06-12 17:43:06 -0700964 allow_tpl = allow_tpl && !cpi->sf.tpl_sf.disable_filtered_key_tpl &&
Bohan Li8e6d8b22021-01-14 14:57:15 -0800965 !cpi->no_show_fwd_kf &&
Mufaddal Chakeraab20d372021-03-17 12:18:34 +0530966 gf_group->update_type[cpi->gf_frame_index] != OVERLAY_UPDATE;
bohanli0db9c512020-06-12 17:43:06 -0700967 } else {
968 // Do tpl after ARF is filtered, or if no ARF, at the second frame of GF
969 // group.
970 // TODO(bohanli): if no ARF, just do it at the first frame.
Mufaddal Chakeraab20d372021-03-17 12:18:34 +0530971 int gf_index = cpi->gf_frame_index;
Jingning Hand5a40c92020-08-13 00:28:28 -0700972 allow_tpl = allow_tpl && (gf_group->update_type[gf_index] == ARF_UPDATE ||
973 gf_group->update_type[gf_index] == GF_UPDATE);
bohanli0db9c512020-06-12 17:43:06 -0700974 if (allow_tpl) {
975 // Need to set the size for TPL for ARF
976 // TODO(bohanli): Why is this? what part of it is necessary?
Urvang Joshi2e592e32020-10-05 23:23:09 -0700977 av1_set_frame_size(cpi, cm->superres_upscaled_width,
978 cm->superres_upscaled_height);
Yunqing Wang8c3f2752020-06-18 16:06:54 -0700979 }
Jingning Han97b64a72019-10-08 11:40:51 -0700980 }
Jingning Handcb4fdc2020-09-22 09:48:56 -0700981
Deepa K G5a6eb3b2020-10-16 20:09:14 +0530982 if (allow_tpl == 0) {
983 // Avoid the use of unintended TPL stats from previous GOP's results.
Mufaddal Chakera7260d142021-04-12 01:03:40 +0530984 if (cpi->gf_frame_index == 0 && !is_stat_generation_stage(cpi))
985 av1_init_tpl_stats(&cpi->ppi->tpl_data);
Deepa K G5a6eb3b2020-10-16 20:09:14 +0530986 } else {
Jingning Han5c01a462021-05-11 13:31:21 -0700987 if (!cpi->skip_tpl_setup_stats) {
988 av1_tpl_preload_rc_estimate(cpi, frame_params);
Deepa K G5a6eb3b2020-10-16 20:09:14 +0530989 av1_tpl_setup_stats(cpi, 0, frame_params, frame_input);
Jingning Han5c01a462021-05-11 13:31:21 -0700990 }
Deepa K G5a6eb3b2020-10-16 20:09:14 +0530991 }
Jingning Han97b64a72019-10-08 11:40:51 -0700992
993 if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
994 AOM_CODEC_OK) {
995 return AOM_CODEC_ERROR;
996 }
997
998 // Set frame_input source to true source for psnr calculation.
Mufaddal Chakeraea4c6d52020-06-12 15:09:14 +0530999 if (apply_filtering && is_psnr_calc_enabled(cpi)) {
Urvang Joshi708a34f2020-10-06 16:05:26 -07001000 cpi->source =
1001 av1_scale_if_required(cm, source_buffer, &cpi->scaled_source,
1002 cm->features.interp_filter, 0, false, true);
bohanli0db9c512020-06-12 17:43:06 -07001003 cpi->unscaled_source = source_buffer;
Jingning Han97b64a72019-10-08 11:40:51 -07001004 }
Yunqing Wang7a3ad542020-11-03 23:40:24 -08001005#if CONFIG_COLLECT_COMPONENT_TIMING
1006 if (cpi->oxcf.pass == 2) end_timing(cpi, denoise_and_encode_time);
1007#endif
Cheng Chen7abe3132019-06-19 11:55:28 -07001008 return AOM_CODEC_OK;
1009}
1010#endif // !CONFIG_REALTIME_ONLY
1011
Hui Su5f7ee812020-02-20 15:58:04 -08001012static INLINE int find_unused_ref_frame(const int *used_ref_frames,
1013 const int *stack, int stack_size) {
1014 for (int i = 0; i < stack_size; ++i) {
1015 const int this_ref = stack[i];
1016 int ref_idx = 0;
1017 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx) {
1018 if (this_ref == used_ref_frames[ref_idx]) break;
1019 }
1020
1021 // not in use
1022 if (ref_idx > ALTREF_FRAME - LAST_FRAME) return this_ref;
1023 }
1024
1025 return INVALID_IDX;
1026}
1027
Angie Chiangd96bce12021-03-24 19:52:18 -07001028void av1_get_ref_frames(const RefBufferStack *ref_buffer_stack,
1029 int remapped_ref_idx[REF_FRAMES]) {
1030 const int *const arf_stack = ref_buffer_stack->arf_stack;
1031 const int *const lst_stack = ref_buffer_stack->lst_stack;
1032 const int *const gld_stack = ref_buffer_stack->gld_stack;
Jingning Han42266ca2019-07-12 14:37:16 -07001033 const int arf_stack_size = ref_buffer_stack->arf_stack_size;
1034 const int lst_stack_size = ref_buffer_stack->lst_stack_size;
1035 const int gld_stack_size = ref_buffer_stack->gld_stack_size;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001036
1037 // Initialization
Hui Su5f7ee812020-02-20 15:58:04 -08001038 for (int i = 0; i < REF_FRAMES; ++i) remapped_ref_idx[i] = INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001039
1040 if (arf_stack_size) {
Hui Su5f7ee812020-02-20 15:58:04 -08001041 remapped_ref_idx[ALTREF_FRAME - LAST_FRAME] = arf_stack[arf_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001042
1043 if (arf_stack_size > 1)
Hui Su5f7ee812020-02-20 15:58:04 -08001044 remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = arf_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001045
1046 if (arf_stack_size > 2)
Hui Su5f7ee812020-02-20 15:58:04 -08001047 remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] = arf_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001048 }
1049
1050 if (lst_stack_size) {
Hui Su5f7ee812020-02-20 15:58:04 -08001051 remapped_ref_idx[LAST_FRAME - LAST_FRAME] = lst_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001052
1053 if (lst_stack_size > 1)
Hui Su5f7ee812020-02-20 15:58:04 -08001054 remapped_ref_idx[LAST2_FRAME - LAST_FRAME] = lst_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001055 }
1056
1057 if (gld_stack_size) {
Hui Su5f7ee812020-02-20 15:58:04 -08001058 remapped_ref_idx[GOLDEN_FRAME - LAST_FRAME] = gld_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001059
Hui Su483d25d2020-04-15 00:28:08 -07001060 // If there are more frames in the golden stack, assign them to BWDREF,
1061 // ALTREF2, or LAST3.
Jingning Han0a2af4e2019-07-08 19:30:03 -07001062 if (gld_stack_size > 1) {
Hui Su483d25d2020-04-15 00:28:08 -07001063 if (arf_stack_size <= 2) {
1064 if (arf_stack_size <= 1) {
1065 remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = gld_stack[1];
1066 if (gld_stack_size > 2)
1067 remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] = gld_stack[2];
1068 } else {
1069 remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] = gld_stack[1];
1070 }
1071 } else {
Hui Su5f7ee812020-02-20 15:58:04 -08001072 remapped_ref_idx[LAST3_FRAME - LAST_FRAME] = gld_stack[1];
Hui Su483d25d2020-04-15 00:28:08 -07001073 }
Jingning Han0a2af4e2019-07-08 19:30:03 -07001074 }
1075 }
1076
1077 for (int idx = ALTREF_FRAME - LAST_FRAME; idx >= 0; --idx) {
Hui Su5f7ee812020-02-20 15:58:04 -08001078 int ref_map_index = remapped_ref_idx[idx];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001079
1080 if (ref_map_index != INVALID_IDX) continue;
1081
Hui Su5f7ee812020-02-20 15:58:04 -08001082 ref_map_index =
1083 find_unused_ref_frame(remapped_ref_idx, arf_stack, arf_stack_size);
Jingning Han0a2af4e2019-07-08 19:30:03 -07001084
Hui Su5f7ee812020-02-20 15:58:04 -08001085 if (ref_map_index == INVALID_IDX) {
1086 ref_map_index =
1087 find_unused_ref_frame(remapped_ref_idx, gld_stack, gld_stack_size);
Jingning Han0a2af4e2019-07-08 19:30:03 -07001088 }
1089
Hui Su5f7ee812020-02-20 15:58:04 -08001090 if (ref_map_index == INVALID_IDX) {
1091 ref_map_index =
1092 find_unused_ref_frame(remapped_ref_idx, lst_stack, lst_stack_size);
Jingning Han0a2af4e2019-07-08 19:30:03 -07001093 }
1094
bohanli99852502020-07-14 16:22:45 -07001095 if (ref_map_index != INVALID_IDX) {
Hui Su5f7ee812020-02-20 15:58:04 -08001096 remapped_ref_idx[idx] = ref_map_index;
bohanli99852502020-07-14 16:22:45 -07001097 } else if (!gld_stack_size && arf_stack_size) {
1098 remapped_ref_idx[idx] = ref_buffer_stack->arf_stack[0];
1099 } else {
Hui Su5f7ee812020-02-20 15:58:04 -08001100 remapped_ref_idx[idx] = ref_buffer_stack->gld_stack[0];
bohanli99852502020-07-14 16:22:45 -07001101 }
Jingning Han0a2af4e2019-07-08 19:30:03 -07001102 }
1103}
1104
David Turner056f7cd2019-01-07 17:48:13 +00001105int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
David Turner1539bb02019-01-24 15:28:13 +00001106 uint8_t *const dest, unsigned int *frame_flags,
David Turnerdedd8ff2019-01-23 13:59:46 +00001107 int64_t *const time_stamp, int64_t *const time_end,
Yue Chen1bc5be62018-08-24 13:57:32 -07001108 const aom_rational64_t *const timestamp_ratio,
1109 int flush) {
Vishesh7e9873d2020-06-08 15:41:33 +05301110 AV1EncoderConfig *const oxcf = &cpi->oxcf;
David Turner475a3132019-01-18 15:17:17 +00001111 AV1_COMMON *const cm = &cpi->common;
Mufaddal Chakera8ee04fa2021-03-17 13:33:18 +05301112 GF_GROUP *gf_group = &cpi->ppi->gf_group;
Vishesha195ca32020-04-07 18:46:20 +05301113 ExternalFlags *const ext_flags = &cpi->ext_flags;
Vishesh5b50e6d2020-06-10 19:20:07 +05301114 GFConfig *const gf_cfg = &oxcf->gf_cfg;
David Turner056f7cd2019-01-07 17:48:13 +00001115
David Turnerdedd8ff2019-01-23 13:59:46 +00001116 EncodeFrameInput frame_input;
David Turner04b70d82019-01-24 15:39:19 +00001117 EncodeFrameParams frame_params;
1118 EncodeFrameResults frame_results;
David Turnerdedd8ff2019-01-23 13:59:46 +00001119 memset(&frame_input, 0, sizeof(frame_input));
David Turner04b70d82019-01-24 15:39:19 +00001120 memset(&frame_params, 0, sizeof(frame_params));
1121 memset(&frame_results, 0, sizeof(frame_results));
1122
Jingning Hand3e827d2020-08-16 16:07:24 -07001123 // Check if we need to stuff more src frames
1124 if (flush == 0) {
1125 int srcbuf_size =
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +05301126 av1_lookahead_depth(cpi->ppi->lookahead, cpi->compressor_stage);
1127 int pop_size =
1128 av1_lookahead_pop_sz(cpi->ppi->lookahead, cpi->compressor_stage);
Jingning Hand3e827d2020-08-16 16:07:24 -07001129
1130 // Continue buffering look ahead buffer.
1131 if (srcbuf_size < pop_size) return -1;
1132 }
1133
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +05301134 if (!av1_lookahead_peek(cpi->ppi->lookahead, 0, cpi->compressor_stage)) {
Jingning Han3f3318f2020-08-16 16:12:10 -07001135#if !CONFIG_REALTIME_ONLY
Mufaddal Chakera358cf212021-02-25 14:41:56 +05301136 if (flush && oxcf->pass == 1 && !cpi->ppi->twopass.first_pass_done) {
Jingning Han3f3318f2020-08-16 16:12:10 -07001137 av1_end_first_pass(cpi); /* get last stats packet */
Mufaddal Chakera358cf212021-02-25 14:41:56 +05301138 cpi->ppi->twopass.first_pass_done = 1;
Jingning Han3f3318f2020-08-16 16:12:10 -07001139 }
1140#endif
1141 return -1;
1142 }
1143
Sarah Parker97803fc2019-05-17 14:15:37 -07001144 // TODO(sarahparker) finish bit allocation for one pass pyramid
Aasaipriya5feffea2020-04-15 12:43:05 +05301145 if (has_no_stats_stage(cpi)) {
Vishesh5b50e6d2020-06-10 19:20:07 +05301146 gf_cfg->gf_max_pyr_height =
1147 AOMMIN(gf_cfg->gf_max_pyr_height, USE_ALTREF_FOR_ONE_PASS);
1148 gf_cfg->gf_min_pyr_height =
1149 AOMMIN(gf_cfg->gf_min_pyr_height, gf_cfg->gf_max_pyr_height);
Urvang Joshib44f48f2020-01-27 11:09:48 -08001150 }
Sarah Parker97803fc2019-05-17 14:15:37 -07001151
Mufaddal Chakera7260d142021-04-12 01:03:40 +05301152 cpi->skip_tpl_setup_stats = 0;
Jingning Han3f3318f2020-08-16 16:12:10 -07001153#if !CONFIG_REALTIME_ONLY
1154 const int use_one_pass_rt_params = has_no_stats_stage(cpi) &&
1155 oxcf->mode == REALTIME &&
1156 gf_cfg->lag_in_frames == 0;
1157 if (!use_one_pass_rt_params && !is_stat_generation_stage(cpi)) {
Yunqing Wang7a3ad542020-11-03 23:40:24 -08001158#if CONFIG_COLLECT_COMPONENT_TIMING
1159 start_timing(cpi, av1_get_second_pass_params_time);
1160#endif
Jingning Han3f3318f2020-08-16 16:12:10 -07001161 av1_get_second_pass_params(cpi, &frame_params, &frame_input, *frame_flags);
Yunqing Wang7a3ad542020-11-03 23:40:24 -08001162#if CONFIG_COLLECT_COMPONENT_TIMING
1163 end_timing(cpi, av1_get_second_pass_params_time);
1164#endif
Jingning Han3f3318f2020-08-16 16:12:10 -07001165 }
1166#endif
1167
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301168 if (!is_stat_generation_stage(cpi)) {
Sarah Parker2beb1d12019-10-25 16:30:32 -07001169 // If this is a forward keyframe, mark as a show_existing_frame
bohanli1629a4b2020-06-11 16:15:14 -07001170 // TODO(bohanli): find a consistent condition for fwd keyframes
Jingning Han2dcb0502020-08-20 20:35:26 -07001171 if (oxcf->kf_cfg.fwd_kf_enabled &&
Mufaddal Chakeraab20d372021-03-17 12:18:34 +05301172 gf_group->update_type[cpi->gf_frame_index] == OVERLAY_UPDATE &&
Jingning Han2dcb0502020-08-20 20:35:26 -07001173 cpi->rc.frames_to_key == 0) {
Sarah Parker2beb1d12019-10-25 16:30:32 -07001174 frame_params.show_existing_frame = 1;
1175 } else {
1176 frame_params.show_existing_frame =
Jingning Han2dcb0502020-08-20 20:35:26 -07001177 (cpi->show_existing_alt_ref &&
Mufaddal Chakeraab20d372021-03-17 12:18:34 +05301178 gf_group->update_type[cpi->gf_frame_index] == OVERLAY_UPDATE) ||
1179 gf_group->update_type[cpi->gf_frame_index] == INTNL_OVERLAY_UPDATE;
Sarah Parker2beb1d12019-10-25 16:30:32 -07001180 }
David Turnere86ee0d2019-02-18 17:16:28 +00001181 frame_params.show_existing_frame &= allow_show_existing(cpi, *frame_flags);
Yunqing Wang1973f112019-10-18 15:50:04 -07001182
1183 // Reset show_existing_alt_ref decision to 0 after it is used.
Mufaddal Chakeraab20d372021-03-17 12:18:34 +05301184 if (gf_group->update_type[cpi->gf_frame_index] == OVERLAY_UPDATE) {
Yunqing Wang1973f112019-10-18 15:50:04 -07001185 cpi->show_existing_alt_ref = 0;
1186 }
David Turnerb0c0aa32019-01-28 16:17:13 +00001187 } else {
David Turnere86ee0d2019-02-18 17:16:28 +00001188 frame_params.show_existing_frame = 0;
David Turnerb0c0aa32019-01-28 16:17:13 +00001189 }
1190
David Turnerdedd8ff2019-01-23 13:59:46 +00001191 struct lookahead_entry *source = NULL;
1192 struct lookahead_entry *last_source = NULL;
Angie Chiang470d1162020-12-31 13:10:55 -08001193 int pop_lookahead = 0;
David Turnere86ee0d2019-02-18 17:16:28 +00001194 if (frame_params.show_existing_frame) {
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +05301195 source = av1_lookahead_peek(cpi->ppi->lookahead, 0, cpi->compressor_stage);
Angie Chiang470d1162020-12-31 13:10:55 -08001196 pop_lookahead = 1;
Jingning Hand392c012019-09-19 15:48:08 -07001197 frame_params.show_frame = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +00001198 } else {
Angie Chiang470d1162020-12-31 13:10:55 -08001199 source = choose_frame_source(cpi, &flush, &pop_lookahead, &last_source,
1200 &frame_params);
David Turnerdedd8ff2019-01-23 13:59:46 +00001201 }
1202
1203 if (source == NULL) { // If no source was found, we can't encode a frame.
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001204#if !CONFIG_REALTIME_ONLY
Mufaddal Chakera358cf212021-02-25 14:41:56 +05301205 if (flush && oxcf->pass == 1 && !cpi->ppi->twopass.first_pass_done) {
David Turnerdedd8ff2019-01-23 13:59:46 +00001206 av1_end_first_pass(cpi); /* get last stats packet */
Mufaddal Chakera358cf212021-02-25 14:41:56 +05301207 cpi->ppi->twopass.first_pass_done = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +00001208 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001209#endif
David Turnerdedd8ff2019-01-23 13:59:46 +00001210 return -1;
1211 }
bohanli0db9c512020-06-12 17:43:06 -07001212 // Source may be changed if temporal filtered later.
1213 frame_input.source = &source->img;
David Turnerdedd8ff2019-01-23 13:59:46 +00001214 frame_input.last_source = last_source != NULL ? &last_source->img : NULL;
1215 frame_input.ts_duration = source->ts_end - source->ts_start;
Cheng Chene1a7a3e2020-03-18 18:23:19 -07001216 // Save unfiltered source. It is used in av1_get_second_pass_params().
1217 cpi->unfiltered_source = frame_input.source;
David Turnerdedd8ff2019-01-23 13:59:46 +00001218
1219 *time_stamp = source->ts_start;
1220 *time_end = source->ts_end;
Yunqing Wang15ab03c2020-11-24 16:45:25 -08001221 if (source->ts_start < cpi->time_stamps.first_ts_start) {
1222 cpi->time_stamps.first_ts_start = source->ts_start;
1223 cpi->time_stamps.prev_ts_end = source->ts_start;
David Turnerdedd8ff2019-01-23 13:59:46 +00001224 }
1225
1226 av1_apply_encoding_flags(cpi, source->flags);
bohanlicbe8e742020-08-17 14:19:17 -07001227 *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
David Turnerdedd8ff2019-01-23 13:59:46 +00001228
Jingning Hand392c012019-09-19 15:48:08 -07001229 // Shown frames and arf-overlay frames need frame-rate considering
Deepa K Gfb89ce02020-04-06 13:34:42 +05301230 if (frame_params.show_frame)
1231 adjust_frame_rate(cpi, source->ts_start, source->ts_end);
David Turnerdedd8ff2019-01-23 13:59:46 +00001232
Jingning Hand392c012019-09-19 15:48:08 -07001233 if (!frame_params.show_existing_frame) {
David Turnerdedd8ff2019-01-23 13:59:46 +00001234 if (cpi->film_grain_table) {
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001235 cm->cur_frame->film_grain_params_present = aom_film_grain_table_lookup(
David Turnerdedd8ff2019-01-23 13:59:46 +00001236 cpi->film_grain_table, *time_stamp, *time_end, 0 /* =erase */,
1237 &cm->film_grain_params);
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001238 } else {
1239 cm->cur_frame->film_grain_params_present =
Tarundeep Singh4243e622021-04-20 16:10:22 +05301240 cm->seq_params->film_grain_params_present;
David Turnerdedd8ff2019-01-23 13:59:46 +00001241 }
David Turnerdedd8ff2019-01-23 13:59:46 +00001242 // only one operating point supported now
Yue Chen1bc5be62018-08-24 13:57:32 -07001243 const int64_t pts64 = ticks_to_timebase_units(timestamp_ratio, *time_stamp);
David Turnerdedd8ff2019-01-23 13:59:46 +00001244 if (pts64 < 0 || pts64 > UINT32_MAX) return AOM_CODEC_ERROR;
Jingning Hand392c012019-09-19 15:48:08 -07001245 cm->frame_presentation_time = (uint32_t)pts64;
David Turnerdedd8ff2019-01-23 13:59:46 +00001246 }
1247
Marco Paniconicea99e22019-07-16 18:36:31 -07001248#if CONFIG_REALTIME_ONLY
1249 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
Tarundeep Singh9e77b302021-03-19 16:07:48 +05301250 if (cpi->oxcf.speed >= 5 && cpi->ppi->number_spatial_layers == 1 &&
1251 cpi->ppi->number_temporal_layers == 1)
Mufaddal Chakeraab20d372021-03-17 12:18:34 +05301252 av1_set_reference_structure_one_pass_rt(cpi, cpi->gf_frame_index == 0);
Marco Paniconicea99e22019-07-16 18:36:31 -07001253#else
chiyotsai8b8f8a22020-04-21 11:03:47 -07001254 if (use_one_pass_rt_params) {
Marco Paniconicea99e22019-07-16 18:36:31 -07001255 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
Tarundeep Singh9e77b302021-03-19 16:07:48 +05301256 if (cpi->oxcf.speed >= 5 && cpi->ppi->number_spatial_layers == 1 &&
1257 cpi->ppi->number_temporal_layers == 1)
Mufaddal Chakeraab20d372021-03-17 12:18:34 +05301258 av1_set_reference_structure_one_pass_rt(cpi, cpi->gf_frame_index == 0);
chiyotsai8b8f8a22020-04-21 11:03:47 -07001259 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001260#endif
Jingning Han3f3318f2020-08-16 16:12:10 -07001261
Mufaddal Chakeraab20d372021-03-17 12:18:34 +05301262 FRAME_UPDATE_TYPE frame_update_type =
1263 get_frame_update_type(gf_group, cpi->gf_frame_index);
David Turner4f1f1812019-01-24 17:00:24 +00001264
David Turnere86ee0d2019-02-18 17:16:28 +00001265 if (frame_params.show_existing_frame &&
1266 frame_params.frame_type != KEY_FRAME) {
David Turner475a3132019-01-18 15:17:17 +00001267 // Force show-existing frames to be INTER, except forward keyframes
1268 frame_params.frame_type = INTER_FRAME;
1269 }
1270
David Turner056f7cd2019-01-07 17:48:13 +00001271 // TODO(david.turner@argondesign.com): Move all the encode strategy
1272 // (largely near av1_get_compressed_data) in here
1273
1274 // TODO(david.turner@argondesign.com): Change all the encode strategy to
1275 // modify frame_params instead of cm or cpi.
1276
bohanli99852502020-07-14 16:22:45 -07001277 // Per-frame encode speed. In theory this can vary, but things may have
1278 // been written assuming speed-level will not change within a sequence, so
1279 // this parameter should be used with caution.
David Turner04b70d82019-01-24 15:39:19 +00001280 frame_params.speed = oxcf->speed;
1281
David Turnerddbff442019-01-21 14:58:42 +00001282 // Work out some encoding parameters specific to the pass:
Vishesh734eff92020-06-20 21:46:36 +05301283 if (has_no_stats_stage(cpi) && oxcf->q_cfg.aq_mode == CYCLIC_REFRESH_AQ) {
Sarah Parker97803fc2019-05-17 14:15:37 -07001284 av1_cyclic_refresh_update_parameters(cpi);
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301285 } else if (is_stat_generation_stage(cpi)) {
Vishesh39e74092020-06-16 17:13:48 +05301286 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&oxcf->rc_cfg);
Jayasanker J312b85e2021-02-23 12:44:30 +05301287 // Current frame is coded as a key-frame for any of the following cases:
1288 // 1) First frame of a video
1289 // 2) For all-intra frame encoding
1290 // 3) When a key-frame is forced
1291 const int kf_requested =
1292 (cm->current_frame.frame_number == 0 ||
1293 oxcf->kf_cfg.key_freq_max == 0 || (*frame_flags & FRAMEFLAGS_KEY));
David Turner4f1f1812019-01-24 17:00:24 +00001294 if (kf_requested && frame_update_type != OVERLAY_UPDATE &&
1295 frame_update_type != INTNL_OVERLAY_UPDATE) {
David Turnerddbff442019-01-21 14:58:42 +00001296 frame_params.frame_type = KEY_FRAME;
1297 } else {
1298 frame_params.frame_type = INTER_FRAME;
David Turnercb5e36f2019-01-17 17:15:25 +00001299 }
Hamsalekha S37cc1d12019-12-12 19:27:41 +05301300 } else if (is_stat_consumption_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001301#if CONFIG_MISMATCH_DEBUG
1302 mismatch_move_frame_idx_w();
1303#endif
1304#if TXCOEFF_COST_TIMER
1305 cm->txcoeff_cost_timer = 0;
1306 cm->txcoeff_cost_count = 0;
1307#endif
1308 }
1309
Vishesha195ca32020-04-07 18:46:20 +05301310 if (!is_stat_generation_stage(cpi))
1311 set_ext_overrides(cm, &frame_params, ext_flags);
David Turnerddbff442019-01-21 14:58:42 +00001312
David Turner4f1f1812019-01-24 17:00:24 +00001313 // Shown keyframes and S frames refresh all reference buffers
1314 const int force_refresh_all =
1315 ((frame_params.frame_type == KEY_FRAME && frame_params.show_frame) ||
1316 frame_params.frame_type == S_FRAME) &&
David Turnere86ee0d2019-02-18 17:16:28 +00001317 !frame_params.show_existing_frame;
David Turner4f1f1812019-01-24 17:00:24 +00001318
Jayasanker J24cb9bc2020-04-15 13:43:10 +05301319 av1_configure_buffer_updates(cpi, &frame_params.refresh_frame,
bohanli99852502020-07-14 16:22:45 -07001320 frame_update_type, frame_params.frame_type,
1321 force_refresh_all);
David Turner4f1f1812019-01-24 17:00:24 +00001322
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301323 if (!is_stat_generation_stage(cpi)) {
Deepa K G140bc832019-10-30 17:16:29 +05301324 const RefCntBuffer *ref_frames[INTER_REFS_PER_FRAME];
1325 const YV12_BUFFER_CONFIG *ref_frame_buf[INTER_REFS_PER_FRAME];
1326
Vishesh38c05d72020-04-14 12:19:14 +05301327 if (!ext_flags->refresh_frame.update_pending) {
Angie Chiangd96bce12021-03-24 19:52:18 -07001328 av1_get_ref_frames(&cpi->ref_buffer_stack, cm->remapped_ref_idx);
Marco Paniconie5de3322021-03-22 22:03:17 -07001329 } else if (cpi->svc.set_ref_frame_config) {
Marco Paniconi67142112019-07-24 15:00:31 -07001330 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++)
1331 cm->remapped_ref_idx[i] = cpi->svc.ref_idx[i];
1332 }
Jingning Han0a2af4e2019-07-08 19:30:03 -07001333
Deepa K G140bc832019-10-30 17:16:29 +05301334 // Get the reference frames
1335 for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
1336 ref_frames[i] = get_ref_frame_buf(cm, ref_frame_priority_order[i]);
1337 ref_frame_buf[i] = ref_frames[i] != NULL ? &ref_frames[i]->buf : NULL;
1338 }
bohanli99852502020-07-14 16:22:45 -07001339
David Turnerddbff442019-01-21 14:58:42 +00001340 // Work out which reference frame slots may be used.
Jingning Hanb16c3da2020-09-22 22:37:02 -07001341 frame_params.ref_frame_flags = get_ref_frame_flags(
1342 &cpi->sf, ref_frame_buf, ext_flags->ref_frame_flags);
David Turnerddbff442019-01-21 14:58:42 +00001343
David Turnera7f133c2019-01-22 14:47:16 +00001344 frame_params.primary_ref_frame =
1345 choose_primary_ref_frame(cpi, &frame_params);
Mufaddal Chakeraab20d372021-03-17 12:18:34 +05301346 frame_params.order_offset = gf_group->arf_src_offset[cpi->gf_frame_index];
David Turner6e8b4d92019-02-18 15:01:33 +00001347
Jingning Han42266ca2019-07-12 14:37:16 -07001348 frame_params.refresh_frame_flags = av1_get_refresh_frame_flags(
1349 cpi, &frame_params, frame_update_type, &cpi->ref_buffer_stack);
Jingning Hana7293932019-08-15 15:46:49 -07001350
1351 frame_params.existing_fb_idx_to_show =
1352 frame_params.show_existing_frame
Debargha Mukherjeea2074dd2019-09-04 10:03:44 -07001353 ? (frame_update_type == INTNL_OVERLAY_UPDATE
1354 ? get_ref_frame_map_idx(cm, BWDREF_FRAME)
1355 : get_ref_frame_map_idx(cm, ALTREF_FRAME))
Jingning Hana7293932019-08-15 15:46:49 -07001356 : INVALID_IDX;
David Turnera7f133c2019-01-22 14:47:16 +00001357 }
1358
David Turner73245762019-02-11 16:42:34 +00001359 // The way frame_params->remapped_ref_idx is setup is a placeholder.
David Turnerf4592292019-02-21 11:50:30 +00001360 // Currently, reference buffer assignment is done by update_ref_frame_map()
bohanli99852502020-07-14 16:22:45 -07001361 // which is called by high-level strategy AFTER encoding a frame. It
1362 // modifies cm->remapped_ref_idx. If you want to use an alternative method
1363 // to determine reference buffer assignment, just put your assignments into
David Turner73245762019-02-11 16:42:34 +00001364 // frame_params->remapped_ref_idx here and they will be used when encoding
1365 // this frame. If frame_params->remapped_ref_idx is setup independently of
David Turnerf4592292019-02-21 11:50:30 +00001366 // cm->remapped_ref_idx then update_ref_frame_map() will have no effect.
David Turner73245762019-02-11 16:42:34 +00001367 memcpy(frame_params.remapped_ref_idx, cm->remapped_ref_idx,
1368 REF_FRAMES * sizeof(*cm->remapped_ref_idx));
1369
Urvang Joshi69a986c2020-04-27 16:13:11 -07001370 cpi->td.mb.delta_qindex = 0;
Yue Chen4e585cc2019-06-03 14:47:16 -07001371
1372 if (!frame_params.show_existing_frame) {
Vishesh734eff92020-06-20 21:46:36 +05301373 cm->quant_params.using_qmatrix = oxcf->q_cfg.using_qm;
Yue Chen4e585cc2019-06-03 14:47:16 -07001374 }
Marco Paniconi34b0dd02020-07-29 16:41:41 -07001375
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001376#if CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +00001377 if (av1_encode(cpi, dest, &frame_input, &frame_params, &frame_results) !=
David Turnerddbff442019-01-21 14:58:42 +00001378 AOM_CODEC_OK) {
1379 return AOM_CODEC_ERROR;
1380 }
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001381#else
Marco Paniconieca11952020-05-06 11:30:48 -07001382 if (has_no_stats_stage(cpi) && oxcf->mode == REALTIME &&
Vishesh5b50e6d2020-06-10 19:20:07 +05301383 gf_cfg->lag_in_frames == 0) {
Marco Paniconieca11952020-05-06 11:30:48 -07001384 if (av1_encode(cpi, dest, &frame_input, &frame_params, &frame_results) !=
1385 AOM_CODEC_OK) {
1386 return AOM_CODEC_ERROR;
1387 }
1388 } else if (denoise_and_encode(cpi, dest, &frame_input, &frame_params,
1389 &frame_results) != AOM_CODEC_OK) {
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001390 return AOM_CODEC_ERROR;
1391 }
1392#endif // CONFIG_REALTIME_ONLY
David Turnerddbff442019-01-21 14:58:42 +00001393
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301394 if (!is_stat_generation_stage(cpi)) {
David Turner73245762019-02-11 16:42:34 +00001395 // First pass doesn't modify reference buffer assignment or produce frame
1396 // flags
Jayasanker J24cb9bc2020-04-15 13:43:10 +05301397 update_frame_flags(&cpi->common, &cpi->refresh_frame, frame_flags);
Vishesh38c05d72020-04-14 12:19:14 +05301398 if (!ext_flags->refresh_frame.update_pending) {
Marco Paniconi8d335b72019-08-06 09:07:07 -07001399 int ref_map_index =
1400 av1_get_refresh_ref_frame_map(cm->current_frame.refresh_frame_flags);
bohanli99852502020-07-14 16:22:45 -07001401 av1_update_ref_frame_map(cpi, frame_update_type, frame_params.frame_type,
1402 cm->show_existing_frame, ref_map_index,
1403 &cpi->ref_buffer_stack);
Marco Paniconi8d335b72019-08-06 09:07:07 -07001404 }
David Turner73245762019-02-11 16:42:34 +00001405 }
1406
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001407#if !CONFIG_REALTIME_ONLY
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301408 if (!is_stat_generation_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001409#if TXCOEFF_COST_TIMER
1410 cm->cum_txcoeff_cost_timer += cm->txcoeff_cost_timer;
1411 fprintf(stderr,
1412 "\ntxb coeff cost block number: %ld, frame time: %ld, cum time %ld "
1413 "in us\n",
1414 cm->txcoeff_cost_count, cm->txcoeff_cost_timer,
1415 cm->cum_txcoeff_cost_timer);
1416#endif
Marco Paniconifb1d0852020-05-05 09:50:05 -07001417 if (!has_no_stats_stage(cpi)) av1_twopass_postencode_update(cpi);
David Turnerddbff442019-01-21 14:58:42 +00001418 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001419#endif // !CONFIG_REALTIME_ONLY
David Turnerddbff442019-01-21 14:58:42 +00001420
Sai Dengaff27722020-08-31 12:06:09 -07001421#if CONFIG_TUNE_VMAF
1422 if (!is_stat_generation_stage(cpi) &&
1423 (oxcf->tune_cfg.tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
1424 oxcf->tune_cfg.tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN)) {
Sai Deng282fad42020-09-17 15:24:29 -07001425 av1_update_vmaf_curve(cpi);
Sai Dengaff27722020-08-31 12:06:09 -07001426 }
1427#endif
Angie Chiang470d1162020-12-31 13:10:55 -08001428 if (pop_lookahead == 1) {
Mufaddal Chakeraa65d2ce2021-02-15 12:20:48 +05301429 av1_lookahead_pop(cpi->ppi->lookahead, flush, cpi->compressor_stage);
Angie Chiang470d1162020-12-31 13:10:55 -08001430 }
Sai Dengaff27722020-08-31 12:06:09 -07001431
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301432 if (!is_stat_generation_stage(cpi)) {
David Turnera7f133c2019-01-22 14:47:16 +00001433 update_fb_of_context_type(cpi, &frame_params, cpi->fb_of_context_type);
David Turner73245762019-02-11 16:42:34 +00001434 set_additional_frame_flags(cm, frame_flags);
David Turnerddbff442019-01-21 14:58:42 +00001435 update_rc_counts(cpi);
David Turner056f7cd2019-01-07 17:48:13 +00001436 }
1437
David Turner1539bb02019-01-24 15:28:13 +00001438 // Unpack frame_results:
David Turner056f7cd2019-01-07 17:48:13 +00001439 *size = frame_results.size;
1440
David Turner1539bb02019-01-24 15:28:13 +00001441 // Leave a signal for a higher level caller about if this frame is droppable
1442 if (*size > 0) {
Vishesh38c05d72020-04-14 12:19:14 +05301443 cpi->droppable = is_frame_droppable(&cpi->svc, &ext_flags->refresh_frame);
David Turner1539bb02019-01-24 15:28:13 +00001444 }
1445
Tarundeep Singh15eb4de2021-04-21 15:53:10 +05301446 if (cpi->ppi->use_svc) av1_save_layer_context(cpi);
Marco Paniconi5b1e4732019-08-08 18:57:53 -07001447
David Turner056f7cd2019-01-07 17:48:13 +00001448 return AOM_CODEC_OK;
1449}