blob: b531bee0e7c0f7b910f7f984e01805133327e47d [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
David Turner1539bb02019-01-24 15:28:13 +000014#include "config/aom_config.h"
David Turnerdedd8ff2019-01-23 13:59:46 +000015#include "config/aom_scale_rtcd.h"
David Turner1539bb02019-01-24 15:28:13 +000016
David Turner056f7cd2019-01-07 17:48:13 +000017#include "aom/aom_codec.h"
David Turnerdedd8ff2019-01-23 13:59:46 +000018#include "aom/aom_encoder.h"
19
20#include "aom_ports/system_state.h"
David Turner056f7cd2019-01-07 17:48:13 +000021
David Turner1539bb02019-01-24 15:28:13 +000022#if CONFIG_MISMATCH_DEBUG
23#include "aom_util/debug_util.h"
24#endif // CONFIG_MISMATCH_DEBUG
25
Wan-Teh Changf2d15ee2020-03-10 09:24:43 -070026#include "av1/common/av1_common_int.h"
Cheng Chen5083a9f2019-07-12 15:33:34 -070027#include "av1/common/reconinter.h"
David Turner07dbd8e2019-01-08 17:16:25 +000028
David Turner056f7cd2019-01-07 17:48:13 +000029#include "av1/encoder/encoder.h"
30#include "av1/encoder/encode_strategy.h"
Cheng Chen5083a9f2019-07-12 15:33:34 -070031#include "av1/encoder/encodeframe.h"
David Turner475a3132019-01-18 15:17:17 +000032#include "av1/encoder/firstpass.h"
David Turner0fa8c492019-02-06 16:38:13 +000033#include "av1/encoder/pass2_strategy.h"
David Turnerdedd8ff2019-01-23 13:59:46 +000034#include "av1/encoder/temporal_filter.h"
David Turner475a3132019-01-18 15:17:17 +000035#include "av1/encoder/tpl_model.h"
David Turner056f7cd2019-01-07 17:48:13 +000036
Cheng Chen7abe3132019-06-19 11:55:28 -070037#define TEMPORAL_FILTER_KEY_FRAME (CONFIG_REALTIME_ONLY ? 0 : 1)
38
Jayasanker J24cb9bc2020-04-15 13:43:10 +053039static INLINE void set_refresh_frame_flags(
40 RefreshFrameFlagsInfo *const refresh_frame_flags, bool refresh_gf,
41 bool refresh_bwdref, bool refresh_arf) {
42 refresh_frame_flags->golden_frame = refresh_gf;
43 refresh_frame_flags->bwd_ref_frame = refresh_bwdref;
44 refresh_frame_flags->alt_ref_frame = refresh_arf;
45}
46
47void av1_configure_buffer_updates(
48 AV1_COMP *const cpi, RefreshFrameFlagsInfo *const refresh_frame_flags,
49 const FRAME_UPDATE_TYPE type, int force_refresh_all) {
David Turnerce9b5902019-01-23 17:25:47 +000050 // NOTE(weitinglin): Should we define another function to take care of
51 // cpi->rc.is_$Source_Type to make this function as it is in the comment?
52
Vishesh38c05d72020-04-14 12:19:14 +053053 const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
54 &cpi->ext_flags.refresh_frame;
David Turner4f1f1812019-01-24 17:00:24 +000055 cpi->rc.is_src_frame_alt_ref = 0;
David Turnerce9b5902019-01-23 17:25:47 +000056
57 switch (type) {
58 case KF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053059 set_refresh_frame_flags(refresh_frame_flags, true, true, true);
David Turnerce9b5902019-01-23 17:25:47 +000060 break;
61
62 case LF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053063 set_refresh_frame_flags(refresh_frame_flags, false, false, false);
David Turnerce9b5902019-01-23 17:25:47 +000064 break;
65
66 case GF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053067 set_refresh_frame_flags(refresh_frame_flags, true, false, false);
David Turnerce9b5902019-01-23 17:25:47 +000068 break;
69
70 case OVERLAY_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053071 set_refresh_frame_flags(refresh_frame_flags, true, false, false);
David Turnerce9b5902019-01-23 17:25:47 +000072 cpi->rc.is_src_frame_alt_ref = 1;
73 break;
74
75 case ARF_UPDATE:
David Turnerce9b5902019-01-23 17:25:47 +000076 // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
Jayasanker J24cb9bc2020-04-15 13:43:10 +053077 set_refresh_frame_flags(refresh_frame_flags, false, false, true);
David Turnerce9b5902019-01-23 17:25:47 +000078 break;
79
David Turnerce9b5902019-01-23 17:25:47 +000080 case INTNL_OVERLAY_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053081 set_refresh_frame_flags(refresh_frame_flags, false, false, false);
David Turnerce9b5902019-01-23 17:25:47 +000082 cpi->rc.is_src_frame_alt_ref = 1;
David Turnerce9b5902019-01-23 17:25:47 +000083 break;
84
85 case INTNL_ARF_UPDATE:
Jayasanker J24cb9bc2020-04-15 13:43:10 +053086 set_refresh_frame_flags(refresh_frame_flags, false, true, false);
David Turnerce9b5902019-01-23 17:25:47 +000087 break;
88
89 default: assert(0); break;
90 }
David Turner4f1f1812019-01-24 17:00:24 +000091
Vishesh38c05d72020-04-14 12:19:14 +053092 if (ext_refresh_frame_flags->update_pending &&
Jayasanker J24cb9bc2020-04-15 13:43:10 +053093 (!is_stat_generation_stage(cpi)))
94 set_refresh_frame_flags(refresh_frame_flags,
95 ext_refresh_frame_flags->golden_frame,
96 ext_refresh_frame_flags->bwd_ref_frame,
97 ext_refresh_frame_flags->alt_ref_frame);
David Turner4f1f1812019-01-24 17:00:24 +000098
Jayasanker J24cb9bc2020-04-15 13:43:10 +053099 if (force_refresh_all)
100 set_refresh_frame_flags(refresh_frame_flags, true, true, true);
David Turnerce9b5902019-01-23 17:25:47 +0000101}
102
David Turner1539bb02019-01-24 15:28:13 +0000103static void set_additional_frame_flags(const AV1_COMMON *const cm,
104 unsigned int *const frame_flags) {
Urvang Joshib6409e92020-03-23 11:23:27 -0700105 if (frame_is_intra_only(cm)) {
106 *frame_flags |= FRAMEFLAGS_INTRAONLY;
107 }
108 if (frame_is_sframe(cm)) {
109 *frame_flags |= FRAMEFLAGS_SWITCH;
110 }
111 if (cm->features.error_resilient_mode) {
112 *frame_flags |= FRAMEFLAGS_ERROR_RESILIENT;
113 }
David Turner1539bb02019-01-24 15:28:13 +0000114}
115
116static INLINE void update_keyframe_counters(AV1_COMP *cpi) {
Urvang Joshi6ce7fbc2019-03-22 15:24:21 -0700117 if (cpi->common.show_frame) {
David Turner1539bb02019-01-24 15:28:13 +0000118 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref ||
119 cpi->common.current_frame.frame_type == KEY_FRAME) {
120 // If this is a show_existing_frame with a source other than altref,
121 // or if it is not a displayed forward keyframe, the keyframe update
122 // counters were incremented when it was originally encoded.
123 cpi->rc.frames_since_key++;
124 cpi->rc.frames_to_key--;
125 }
126 }
127}
128
Vishesh38c05d72020-04-14 12:19:14 +0530129static INLINE int is_frame_droppable(
130 const SVC *const svc,
131 const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags) {
Jingning Han98d20de2019-08-14 12:59:47 -0700132 // Droppable frame is only used by external refresh flags. VoD setting won't
133 // trigger its use case.
Vishesha195ca32020-04-07 18:46:20 +0530134 if (svc->external_ref_frame_config)
135 return svc->non_reference_frame;
Vishesh38c05d72020-04-14 12:19:14 +0530136 else if (ext_refresh_frame_flags->update_pending)
137 return !(ext_refresh_frame_flags->alt_ref_frame ||
138 ext_refresh_frame_flags->alt2_ref_frame ||
139 ext_refresh_frame_flags->bwd_ref_frame ||
140 ext_refresh_frame_flags->golden_frame ||
141 ext_refresh_frame_flags->last_frame);
Marco Paniconi91a50022019-08-01 18:56:39 -0700142 else
Jingning Han98d20de2019-08-14 12:59:47 -0700143 return 0;
David Turner1539bb02019-01-24 15:28:13 +0000144}
145
146static INLINE void update_frames_till_gf_update(AV1_COMP *cpi) {
147 // TODO(weitinglin): Updating this counter for is_frame_droppable
148 // is a work-around to handle the condition when a frame is drop.
149 // We should fix the cpi->common.show_frame flag
150 // instead of checking the other condition to update the counter properly.
Vishesha195ca32020-04-07 18:46:20 +0530151 if (cpi->common.show_frame ||
Vishesh38c05d72020-04-14 12:19:14 +0530152 is_frame_droppable(&cpi->svc, &cpi->ext_flags.refresh_frame)) {
David Turner1539bb02019-01-24 15:28:13 +0000153 // Decrement count down till next gf
154 if (cpi->rc.frames_till_gf_update_due > 0)
155 cpi->rc.frames_till_gf_update_due--;
156 }
157}
158
Sarah Parker97803fc2019-05-17 14:15:37 -0700159static INLINE void update_gf_group_index(AV1_COMP *cpi) {
David Turner1539bb02019-01-24 15:28:13 +0000160 // Increment the gf group index ready for the next frame. If this is
161 // a show_existing_frame with a source other than altref, or if it is not
162 // a displayed forward keyframe, the index was incremented when it was
163 // originally encoded.
164 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref ||
165 cpi->common.current_frame.frame_type == KEY_FRAME) {
Sarah Parkere1b22012019-06-06 16:35:25 -0700166 ++cpi->gf_group.index;
David Turner1539bb02019-01-24 15:28:13 +0000167 }
168}
169
170static void update_rc_counts(AV1_COMP *cpi) {
171 update_keyframe_counters(cpi);
172 update_frames_till_gf_update(cpi);
Sarah Parker97803fc2019-05-17 14:15:37 -0700173 update_gf_group_index(cpi);
David Turner1539bb02019-01-24 15:28:13 +0000174}
175
Vishesha195ca32020-04-07 18:46:20 +0530176static void set_ext_overrides(AV1_COMMON *const cm,
177 EncodeFrameParams *const frame_params,
178 ExternalFlags *const ext_flags) {
David Turner07dbd8e2019-01-08 17:16:25 +0000179 // Overrides the defaults with the externally supplied values with
180 // av1_update_reference() and av1_update_entropy() calls
181 // Note: The overrides are valid only for the next frame passed
182 // to av1_encode_lowlevel()
183
Vishesha195ca32020-04-07 18:46:20 +0530184 if (ext_flags->use_s_frame) {
David Turner475a3132019-01-18 15:17:17 +0000185 frame_params->frame_type = S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000186 }
David Turner07dbd8e2019-01-08 17:16:25 +0000187
Vishesha195ca32020-04-07 18:46:20 +0530188 if (ext_flags->refresh_frame_context_pending) {
189 cm->features.refresh_frame_context = ext_flags->refresh_frame_context;
190 ext_flags->refresh_frame_context_pending = 0;
David Turner07dbd8e2019-01-08 17:16:25 +0000191 }
Vishesha195ca32020-04-07 18:46:20 +0530192 cm->features.allow_ref_frame_mvs = ext_flags->use_ref_frame_mvs;
David Turner07dbd8e2019-01-08 17:16:25 +0000193
Vishesha195ca32020-04-07 18:46:20 +0530194 frame_params->error_resilient_mode = ext_flags->use_error_resilient;
David Turner07dbd8e2019-01-08 17:16:25 +0000195 // A keyframe is already error resilient and keyframes with
196 // error_resilient_mode interferes with the use of show_existing_frame
197 // when forward reference keyframes are enabled.
David Turner475a3132019-01-18 15:17:17 +0000198 frame_params->error_resilient_mode &= frame_params->frame_type != KEY_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000199 // For bitstream conformance, s-frames must be error-resilient
David Turner475a3132019-01-18 15:17:17 +0000200 frame_params->error_resilient_mode |= frame_params->frame_type == S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000201}
202
David Turnera7f133c2019-01-22 14:47:16 +0000203static int get_current_frame_ref_type(
204 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
David Turnera7f133c2019-01-22 14:47:16 +0000205 // We choose the reference "type" of this frame from the flags which indicate
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700206 // which reference frames will be refreshed by it. More than one of these
207 // flags may be set, so the order here implies an order of precedence. This is
208 // just used to choose the primary_ref_frame (as the most recent reference
209 // buffer of the same reference-type as the current frame)
David Turnera7f133c2019-01-22 14:47:16 +0000210
Jingning Han370d1162019-07-03 10:24:03 -0700211 (void)frame_params;
212 // TODO(jingning): This table should be a lot simpler with the new
213 // ARF system in place. Keep frame_params for the time being as we are
214 // still evaluating a few design options.
215 switch (cpi->gf_group.layer_depth[cpi->gf_group.index]) {
216 case 0: return 0;
217 case 1: return 1;
218 case MAX_ARF_LAYERS:
219 case MAX_ARF_LAYERS + 1: return 4;
220 default: return 7;
221 }
David Turnera7f133c2019-01-22 14:47:16 +0000222}
223
224static int choose_primary_ref_frame(
225 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
226 const AV1_COMMON *const cm = &cpi->common;
227
228 const int intra_only = frame_params->frame_type == KEY_FRAME ||
229 frame_params->frame_type == INTRA_ONLY_FRAME;
Marco Paniconi5b1e4732019-08-08 18:57:53 -0700230 if (intra_only || frame_params->error_resilient_mode || cpi->use_svc ||
Vishesha195ca32020-04-07 18:46:20 +0530231 cpi->ext_flags.use_primary_ref_none) {
David Turnera7f133c2019-01-22 14:47:16 +0000232 return PRIMARY_REF_NONE;
233 }
234
Yunqing Wangd0f0d3b2019-12-23 12:15:44 -0800235 // In large scale case, always use Last frame's frame contexts.
236 // Note(yunqing): In other cases, primary_ref_frame is chosen based on
237 // cpi->gf_group.layer_depth[cpi->gf_group.index], which also controls
238 // frame bit allocation.
Urvang Joshi54ffae72020-03-23 13:37:10 -0700239 if (cm->tiles.large_scale) return (LAST_FRAME - LAST_FRAME);
Yunqing Wangd0f0d3b2019-12-23 12:15:44 -0800240
David Turnera7f133c2019-01-22 14:47:16 +0000241 // Find the most recent reference frame with the same reference type as the
242 // current frame
Jingning Han6d878912020-02-28 10:23:35 -0800243 const int current_ref_type = get_current_frame_ref_type(cpi, frame_params);
David Turnera7f133c2019-01-22 14:47:16 +0000244 int wanted_fb = cpi->fb_of_context_type[current_ref_type];
245
246 int primary_ref_frame = PRIMARY_REF_NONE;
247 for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
248 if (get_ref_frame_map_idx(cm, ref_frame) == wanted_fb) {
249 primary_ref_frame = ref_frame - LAST_FRAME;
250 }
251 }
Jingning Han370d1162019-07-03 10:24:03 -0700252
David Turnera7f133c2019-01-22 14:47:16 +0000253 return primary_ref_frame;
254}
255
256static void update_fb_of_context_type(
257 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params,
258 int *const fb_of_context_type) {
259 const AV1_COMMON *const cm = &cpi->common;
Jingning Han370d1162019-07-03 10:24:03 -0700260 const int current_frame_ref_type =
261 get_current_frame_ref_type(cpi, frame_params);
David Turnera7f133c2019-01-22 14:47:16 +0000262
Urvang Joshib6409e92020-03-23 11:23:27 -0700263 if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
Vishesha195ca32020-04-07 18:46:20 +0530264 cpi->ext_flags.use_primary_ref_none) {
David Turnera7f133c2019-01-22 14:47:16 +0000265 for (int i = 0; i < REF_FRAMES; i++) {
266 fb_of_context_type[i] = -1;
267 }
Jingning Han370d1162019-07-03 10:24:03 -0700268 fb_of_context_type[current_frame_ref_type] =
David Turnera7f133c2019-01-22 14:47:16 +0000269 cm->show_frame ? get_ref_frame_map_idx(cm, GOLDEN_FRAME)
270 : get_ref_frame_map_idx(cm, ALTREF_FRAME);
271 }
272
273 if (!encode_show_existing_frame(cm)) {
274 // Refresh fb_of_context_type[]: see encoder.h for explanation
David Turnera7f133c2019-01-22 14:47:16 +0000275 if (cm->current_frame.frame_type == KEY_FRAME) {
276 // All ref frames are refreshed, pick one that will live long enough
Jingning Han370d1162019-07-03 10:24:03 -0700277 fb_of_context_type[current_frame_ref_type] = 0;
David Turnera7f133c2019-01-22 14:47:16 +0000278 } else {
279 // If more than one frame is refreshed, it doesn't matter which one we
280 // pick so pick the first. LST sometimes doesn't refresh any: this is ok
Jingning Han370d1162019-07-03 10:24:03 -0700281
David Turnera7f133c2019-01-22 14:47:16 +0000282 for (int i = 0; i < REF_FRAMES; i++) {
283 if (cm->current_frame.refresh_frame_flags & (1 << i)) {
284 fb_of_context_type[current_frame_ref_type] = i;
285 break;
286 }
287 }
288 }
289 }
290}
291
David Turnere86ee0d2019-02-18 17:16:28 +0000292static int get_order_offset(const GF_GROUP *const gf_group,
David Turnerdedd8ff2019-01-23 13:59:46 +0000293 const EncodeFrameParams *const frame_params) {
David Turnera7f133c2019-01-22 14:47:16 +0000294 // shown frame by definition has order offset 0
295 // show_existing_frame ignores order_offset and simply takes the order_hint
296 // from the reference frame being shown.
David Turnere86ee0d2019-02-18 17:16:28 +0000297 if (frame_params->show_frame || frame_params->show_existing_frame) return 0;
David Turnera7f133c2019-01-22 14:47:16 +0000298
David Turnera7f133c2019-01-22 14:47:16 +0000299 const int arf_offset =
300 AOMMIN((MAX_GF_INTERVAL - 1), gf_group->arf_src_offset[gf_group->index]);
Urvang Joshi6ce7fbc2019-03-22 15:24:21 -0700301 return AOMMIN((MAX_GF_INTERVAL - 1), arf_offset);
David Turnera7f133c2019-01-22 14:47:16 +0000302}
303
Deepa K Gfb89ce02020-04-06 13:34:42 +0530304static void adjust_frame_rate(AV1_COMP *cpi, int64_t ts_start, int64_t ts_end) {
305 TimeStamps *time_stamps = &cpi->time_stamps;
David Turnerdedd8ff2019-01-23 13:59:46 +0000306 int64_t this_duration;
307 int step = 0;
308
309 // Clear down mmx registers
310 aom_clear_system_state();
311
Marco Paniconi63971322019-08-15 21:32:05 -0700312 if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
313 cpi->framerate = cpi->svc.base_framerate;
314 av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
315 return;
316 }
317
Deepa K Gfb89ce02020-04-06 13:34:42 +0530318 if (ts_start == time_stamps->first_ever) {
319 this_duration = ts_end - ts_start;
David Turnerdedd8ff2019-01-23 13:59:46 +0000320 step = 1;
321 } else {
322 int64_t last_duration =
Deepa K Gfb89ce02020-04-06 13:34:42 +0530323 time_stamps->prev_end_seen - time_stamps->prev_start_seen;
David Turnerdedd8ff2019-01-23 13:59:46 +0000324
Deepa K Gfb89ce02020-04-06 13:34:42 +0530325 this_duration = ts_end - time_stamps->prev_end_seen;
David Turnerdedd8ff2019-01-23 13:59:46 +0000326
327 // do a step update if the duration changes by 10%
328 if (last_duration)
329 step = (int)((this_duration - last_duration) * 10 / last_duration);
330 }
331
332 if (this_duration) {
333 if (step) {
334 av1_new_framerate(cpi, 10000000.0 / this_duration);
335 } else {
336 // Average this frame's rate into the last second's average
337 // frame rate. If we haven't seen 1 second yet, then average
338 // over the whole interval seen.
Deepa K Gfb89ce02020-04-06 13:34:42 +0530339 const double interval =
340 AOMMIN((double)(ts_end - time_stamps->first_ever), 10000000.0);
David Turnerdedd8ff2019-01-23 13:59:46 +0000341 double avg_duration = 10000000.0 / cpi->framerate;
342 avg_duration *= (interval - avg_duration + this_duration);
343 avg_duration /= interval;
344
345 av1_new_framerate(cpi, 10000000.0 / avg_duration);
346 }
347 }
Deepa K Gfb89ce02020-04-06 13:34:42 +0530348 time_stamps->prev_start_seen = ts_start;
349 time_stamps->prev_end_seen = ts_end;
David Turnerdedd8ff2019-01-23 13:59:46 +0000350}
351
Urvang Joshif70375a2019-03-22 23:30:19 -0700352// If this is an alt-ref, returns the offset of the source frame used
353// as the arf midpoint. Otherwise, returns 0.
Jingning Hanf39a1ea2019-08-16 10:43:08 -0700354static int get_arf_src_index(GF_GROUP *gf_group, int pass) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000355 int arf_src_index = 0;
Jingning Hanf39a1ea2019-08-16 10:43:08 -0700356 if (pass != 1) arf_src_index = gf_group->arf_src_offset[gf_group->index];
Jingning Hanbb782982019-08-15 11:28:46 -0700357 return arf_src_index;
David Turnerdedd8ff2019-01-23 13:59:46 +0000358}
359
360// Called if this frame is an ARF or ARF2. Also handles forward-keyframes
361// For an ARF set arf2=0, for ARF2 set arf2=1
362// temporal_filtered is set to 1 if we temporally filter the ARF frame, so that
363// the correct post-filter buffer can be used.
Jingning Hanbb782982019-08-15 11:28:46 -0700364static struct lookahead_entry *setup_arf_frame(
365 AV1_COMP *const cpi, const int arf_src_index, int *code_arf,
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700366 EncodeFrameParams *const frame_params, int *show_existing_alt_ref) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000367 AV1_COMMON *const cm = &cpi->common;
368 RATE_CONTROL *const rc = &cpi->rc;
Jerome Jiang71647472019-05-30 12:01:57 -0700369#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +0000370 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Jerome Jiang71647472019-05-30 12:01:57 -0700371#endif
David Turnerdedd8ff2019-01-23 13:59:46 +0000372
373 assert(arf_src_index <= rc->frames_to_key);
Jingning Hanbb782982019-08-15 11:28:46 -0700374 *code_arf = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000375
376 struct lookahead_entry *source =
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530377 av1_lookahead_peek(cpi->lookahead, arf_src_index, cpi->compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000378
379 if (source != NULL) {
380 cm->showable_frame = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +0000381
382 // When arf_src_index == rc->frames_to_key, it indicates a fwd_kf
Jingning Hanbb782982019-08-15 11:28:46 -0700383 if (arf_src_index == rc->frames_to_key) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000384 // Skip temporal filtering and mark as intra_only if we have a fwd_kf
David Turnerdedd8ff2019-01-23 13:59:46 +0000385 cpi->no_show_kf = 1;
386 } else {
Jerome Jiang71647472019-05-30 12:01:57 -0700387#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +0000388 if (oxcf->arnr_max_frames > 0) {
389 // Produce the filtered ARF frame.
Yunqing Wang1973f112019-10-18 15:50:04 -0700390 cm->current_frame.frame_type = INTER_FRAME;
391 FRAME_UPDATE_TYPE frame_update_type =
392 get_frame_update_type(&cpi->gf_group);
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530393 av1_configure_buffer_updates(cpi, &frame_params->refresh_frame,
394 frame_update_type, 0);
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700395 *code_arf =
396 av1_temporal_filter(cpi, arf_src_index, show_existing_alt_ref);
Yunqing Wangb0d52fa2019-10-10 13:09:38 -0700397 if (*code_arf) {
398 aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
399 }
David Turnerdedd8ff2019-01-23 13:59:46 +0000400 }
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700401#else
402 (void)show_existing_alt_ref;
Jerome Jiang71647472019-05-30 12:01:57 -0700403#endif
David Turnerdedd8ff2019-01-23 13:59:46 +0000404 }
405 frame_params->show_frame = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000406 }
407 rc->source_alt_ref_pending = 0;
408 return source;
409}
410
411// Determine whether there is a forced keyframe pending in the lookahead buffer
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530412int is_forced_keyframe_pending(struct lookahead_ctx *lookahead,
413 const int up_to_index,
414 const COMPRESSOR_STAGE compressor_stage) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000415 for (int i = 0; i <= up_to_index; i++) {
Mufaddal Chakera73b7b702019-12-09 11:44:55 +0530416 const struct lookahead_entry *e =
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530417 av1_lookahead_peek(lookahead, i, compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000418 if (e == NULL) {
419 // We have reached the end of the lookahead buffer and not early-returned
420 // so there isn't a forced key-frame pending.
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530421 return -1;
David Turnerdedd8ff2019-01-23 13:59:46 +0000422 } else if (e->flags == AOM_EFLAG_FORCE_KF) {
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530423 return (i + 1);
David Turnerdedd8ff2019-01-23 13:59:46 +0000424 } else {
425 continue;
426 }
427 }
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530428 return -1; // Never reached
David Turnerdedd8ff2019-01-23 13:59:46 +0000429}
430
Urvang Joshif70375a2019-03-22 23:30:19 -0700431// Check if we should encode an ARF or internal ARF. If not, try a LAST
David Turnerdedd8ff2019-01-23 13:59:46 +0000432// Do some setup associated with the chosen source
David Turner4f1f1812019-01-24 17:00:24 +0000433// temporal_filtered, flush, and frame_update_type are outputs.
David Turnerdedd8ff2019-01-23 13:59:46 +0000434// Return the frame source, or NULL if we couldn't find one
Yaowu Xufac3d862019-04-26 15:43:03 -0700435static struct lookahead_entry *choose_frame_source(
Jingning Hanbb782982019-08-15 11:28:46 -0700436 AV1_COMP *const cpi, int *const code_arf, int *const flush,
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700437 struct lookahead_entry **last_source, EncodeFrameParams *const frame_params,
438 int *show_existing_alt_ref) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000439 AV1_COMMON *const cm = &cpi->common;
440 struct lookahead_entry *source = NULL;
Jingning Hanbb782982019-08-15 11:28:46 -0700441 *code_arf = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000442
443 // Should we encode an alt-ref frame.
Jingning Hanf39a1ea2019-08-16 10:43:08 -0700444 int arf_src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
Aasaipriya9bc1dcb2020-03-13 17:46:07 +0530445 // TODO(Aasaipriya): Forced key frames need to be fixed when rc_mode != AOM_Q
446 if (arf_src_index &&
447 (is_forced_keyframe_pending(cpi->lookahead, arf_src_index,
448 cpi->compressor_stage) != -1) &&
449 cpi->oxcf.rc_mode != AOM_Q) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000450 arf_src_index = 0;
451 *flush = 1;
452 }
453
Jingning Hanbb782982019-08-15 11:28:46 -0700454 if (arf_src_index)
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700455 source = setup_arf_frame(cpi, arf_src_index, code_arf, frame_params,
456 show_existing_alt_ref);
David Turnerdedd8ff2019-01-23 13:59:46 +0000457
David Turnerdedd8ff2019-01-23 13:59:46 +0000458 if (!source) {
459 // Get last frame source.
460 if (cm->current_frame.frame_number > 0) {
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530461 *last_source =
462 av1_lookahead_peek(cpi->lookahead, -1, cpi->compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000463 }
464 // Read in the source frame.
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530465 source = av1_lookahead_pop(cpi->lookahead, *flush, cpi->compressor_stage);
David Turner4f1f1812019-01-24 17:00:24 +0000466 if (source == NULL) return NULL;
David Turner4f1f1812019-01-24 17:00:24 +0000467 frame_params->show_frame = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +0000468 }
469 return source;
470}
471
David Turnerb0c0aa32019-01-28 16:17:13 +0000472// Don't allow a show_existing_frame to coincide with an error resilient or
473// S-Frame. An exception can be made in the case of a keyframe, since it does
474// not depend on any previous frames.
David Turner73245762019-02-11 16:42:34 +0000475static int allow_show_existing(const AV1_COMP *const cpi,
476 unsigned int frame_flags) {
David Turnerb0c0aa32019-01-28 16:17:13 +0000477 if (cpi->common.current_frame.frame_number == 0) return 0;
478
479 const struct lookahead_entry *lookahead_src =
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530480 av1_lookahead_peek(cpi->lookahead, 0, cpi->compressor_stage);
David Turnerb0c0aa32019-01-28 16:17:13 +0000481 if (lookahead_src == NULL) return 1;
482
483 const int is_error_resilient =
484 cpi->oxcf.error_resilient_mode ||
485 (lookahead_src->flags & AOM_EFLAG_ERROR_RESILIENT);
486 const int is_s_frame =
487 cpi->oxcf.s_frame_mode || (lookahead_src->flags & AOM_EFLAG_SET_S_FRAME);
488 const int is_key_frame =
David Turner73245762019-02-11 16:42:34 +0000489 (cpi->rc.frames_to_key == 0) || (frame_flags & FRAMEFLAGS_KEY);
David Turnerb0c0aa32019-01-28 16:17:13 +0000490 return !(is_error_resilient || is_s_frame) || is_key_frame;
491}
492
David Turner73245762019-02-11 16:42:34 +0000493// Update frame_flags to tell the encoder's caller what sort of frame was
494// encoded.
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530495static void update_frame_flags(
496 const AV1_COMMON *const cm,
497 const RefreshFrameFlagsInfo *const refresh_frame_flags,
498 unsigned int *frame_flags) {
499 if (encode_show_existing_frame(cm)) {
David Turner73245762019-02-11 16:42:34 +0000500 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
501 *frame_flags &= ~FRAMEFLAGS_BWDREF;
502 *frame_flags &= ~FRAMEFLAGS_ALTREF;
503 *frame_flags &= ~FRAMEFLAGS_KEY;
504 return;
505 }
506
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530507 if (refresh_frame_flags->golden_frame) {
David Turner73245762019-02-11 16:42:34 +0000508 *frame_flags |= FRAMEFLAGS_GOLDEN;
509 } else {
510 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
511 }
512
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530513 if (refresh_frame_flags->alt_ref_frame) {
David Turner73245762019-02-11 16:42:34 +0000514 *frame_flags |= FRAMEFLAGS_ALTREF;
515 } else {
516 *frame_flags &= ~FRAMEFLAGS_ALTREF;
517 }
518
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530519 if (refresh_frame_flags->bwd_ref_frame) {
David Turner73245762019-02-11 16:42:34 +0000520 *frame_flags |= FRAMEFLAGS_BWDREF;
521 } else {
522 *frame_flags &= ~FRAMEFLAGS_BWDREF;
523 }
524
Jayasanker J24cb9bc2020-04-15 13:43:10 +0530525 if (cm->current_frame.frame_type == KEY_FRAME) {
David Turner73245762019-02-11 16:42:34 +0000526 *frame_flags |= FRAMEFLAGS_KEY;
527 } else {
528 *frame_flags &= ~FRAMEFLAGS_KEY;
529 }
530}
531
532#define DUMP_REF_FRAME_IMAGES 0
533
534#if DUMP_REF_FRAME_IMAGES == 1
535static int dump_one_image(AV1_COMMON *cm,
536 const YV12_BUFFER_CONFIG *const ref_buf,
537 char *file_name) {
538 int h;
539 FILE *f_ref = NULL;
540
541 if (ref_buf == NULL) {
542 printf("Frame data buffer is NULL.\n");
543 return AOM_CODEC_MEM_ERROR;
544 }
545
546 if ((f_ref = fopen(file_name, "wb")) == NULL) {
547 printf("Unable to open file %s to write.\n", file_name);
548 return AOM_CODEC_MEM_ERROR;
549 }
550
551 // --- Y ---
552 for (h = 0; h < cm->height; ++h) {
553 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
554 }
555 // --- U ---
556 for (h = 0; h < (cm->height >> 1); ++h) {
557 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
558 f_ref);
559 }
560 // --- V ---
561 for (h = 0; h < (cm->height >> 1); ++h) {
562 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
563 f_ref);
564 }
565
566 fclose(f_ref);
567
568 return AOM_CODEC_OK;
569}
570
571static void dump_ref_frame_images(AV1_COMP *cpi) {
572 AV1_COMMON *const cm = &cpi->common;
573 MV_REFERENCE_FRAME ref_frame;
574
575 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
576 char file_name[256] = "";
577 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
578 cm->current_frame.frame_number, ref_frame);
579 dump_one_image(cm, get_ref_frame_yv12_buf(cpi, ref_frame), file_name);
580 }
581}
582#endif // DUMP_REF_FRAME_IMAGES == 1
583
Jingning Han81d6fbb2019-07-15 10:14:13 -0700584int av1_get_refresh_ref_frame_map(int refresh_frame_flags) {
Jingning Hanf58175c2019-07-07 15:02:00 -0700585 int ref_map_index = INVALID_IDX;
586
587 for (ref_map_index = 0; ref_map_index < REF_FRAMES; ++ref_map_index)
588 if ((refresh_frame_flags >> ref_map_index) & 1) break;
589
590 return ref_map_index;
591}
592
Jingning Han4711eb12019-08-01 09:56:59 -0700593static void update_arf_stack(int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700594 RefBufferStack *ref_buffer_stack) {
Jingning Han42266ca2019-07-12 14:37:16 -0700595 if (ref_buffer_stack->arf_stack_size >= 0) {
596 if (ref_buffer_stack->arf_stack[0] == ref_map_index)
597 stack_pop(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size);
Jingning Hanf58175c2019-07-07 15:02:00 -0700598 }
599
Jingning Han42266ca2019-07-12 14:37:16 -0700600 if (ref_buffer_stack->lst_stack_size) {
601 for (int i = ref_buffer_stack->lst_stack_size - 1; i >= 0; --i) {
602 if (ref_buffer_stack->lst_stack[i] == ref_map_index) {
603 for (int idx = i; idx < ref_buffer_stack->lst_stack_size - 1; ++idx)
604 ref_buffer_stack->lst_stack[idx] =
605 ref_buffer_stack->lst_stack[idx + 1];
Cheng Chenc86d2bf2019-09-05 15:07:47 -0700606 ref_buffer_stack->lst_stack[ref_buffer_stack->lst_stack_size - 1] =
607 INVALID_IDX;
Jingning Han42266ca2019-07-12 14:37:16 -0700608 --ref_buffer_stack->lst_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700609 }
610 }
611 }
612
Jingning Han42266ca2019-07-12 14:37:16 -0700613 if (ref_buffer_stack->gld_stack_size) {
614 for (int i = ref_buffer_stack->gld_stack_size - 1; i >= 0; --i) {
615 if (ref_buffer_stack->gld_stack[i] == ref_map_index) {
616 for (int idx = i; idx < ref_buffer_stack->gld_stack_size - 1; ++idx)
617 ref_buffer_stack->gld_stack[idx] =
618 ref_buffer_stack->gld_stack[idx + 1];
Cheng Chenc86d2bf2019-09-05 15:07:47 -0700619 ref_buffer_stack->gld_stack[ref_buffer_stack->gld_stack_size - 1] =
620 INVALID_IDX;
Jingning Han42266ca2019-07-12 14:37:16 -0700621 --ref_buffer_stack->gld_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700622 }
623 }
624 }
625}
626
Jingning Han647f2d12019-07-23 14:15:42 -0700627// Update reference frame stack info.
Jingning Han42266ca2019-07-12 14:37:16 -0700628void av1_update_ref_frame_map(AV1_COMP *cpi,
629 FRAME_UPDATE_TYPE frame_update_type,
Sarah Parkeredffc652019-10-25 16:30:32 -0700630 int show_existing_frame, int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700631 RefBufferStack *ref_buffer_stack) {
David Turner73245762019-02-11 16:42:34 +0000632 AV1_COMMON *const cm = &cpi->common;
Jingning Han47aaf872019-07-21 14:56:32 -0700633 // TODO(jingning): Consider the S-frame same as key frame for the
634 // reference frame tracking purpose. The logic might be better
635 // expressed than converting the frame update type.
636 if (frame_is_sframe(cm)) frame_update_type = KEY_FRAME;
637
Vishesh38c05d72020-04-14 12:19:14 +0530638 if (is_frame_droppable(&cpi->svc, &cpi->ext_flags.refresh_frame)) return;
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700639
Jingning Han81d6fbb2019-07-15 10:14:13 -0700640 switch (frame_update_type) {
641 case KEY_FRAME:
Sarah Parkeredffc652019-10-25 16:30:32 -0700642 if (show_existing_frame)
643 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
644 &ref_buffer_stack->arf_stack_size);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700645 stack_reset(ref_buffer_stack->lst_stack,
646 &ref_buffer_stack->lst_stack_size);
647 stack_reset(ref_buffer_stack->gld_stack,
648 &ref_buffer_stack->gld_stack_size);
649 stack_reset(ref_buffer_stack->arf_stack,
650 &ref_buffer_stack->arf_stack_size);
651 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
652 ref_map_index);
653 break;
654 case GF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700655 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700656 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
657 ref_map_index);
Fyodor Kyslov915b9b82019-11-11 11:53:03 -0800658 // For nonrd_mode: update LAST as well on GF_UPDATE frame.
chiyotsai56681b52019-12-16 11:15:25 -0800659 if (cpi->sf.rt_sf.use_nonrd_pick_mode)
Marco Paniconifa29e162019-08-05 18:08:04 -0700660 stack_push(ref_buffer_stack->lst_stack,
661 &ref_buffer_stack->lst_stack_size, ref_map_index);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700662 break;
663 case LF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700664 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700665 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
666 ref_map_index);
667 break;
668 case ARF_UPDATE:
669 case INTNL_ARF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700670 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700671 stack_push(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size,
672 ref_map_index);
673 break;
674 case OVERLAY_UPDATE:
Jingning Han5738e032019-07-22 15:22:52 -0700675 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
676 &ref_buffer_stack->arf_stack_size);
677 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
678 ref_map_index);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700679 break;
680 case INTNL_OVERLAY_UPDATE:
681 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
682 &ref_buffer_stack->arf_stack_size);
683 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
684 ref_map_index);
685 break;
686 default: assert(0 && "unknown type");
Jingning Hancf6d3252019-07-03 14:26:45 -0700687 }
Jingning Han84a70502019-07-19 11:38:14 -0700688 return;
David Turner73245762019-02-11 16:42:34 +0000689}
690
Jingning Han42266ca2019-07-12 14:37:16 -0700691static int get_free_ref_map_index(const RefBufferStack *ref_buffer_stack) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700692 for (int idx = 0; idx < REF_FRAMES; ++idx) {
693 int is_free = 1;
Jingning Han42266ca2019-07-12 14:37:16 -0700694 for (int i = 0; i < ref_buffer_stack->arf_stack_size; ++i) {
695 if (ref_buffer_stack->arf_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700696 is_free = 0;
697 break;
698 }
699 }
700
Jingning Han42266ca2019-07-12 14:37:16 -0700701 for (int i = 0; i < ref_buffer_stack->lst_stack_size; ++i) {
702 if (ref_buffer_stack->lst_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700703 is_free = 0;
704 break;
705 }
706 }
707
Jingning Han42266ca2019-07-12 14:37:16 -0700708 for (int i = 0; i < ref_buffer_stack->gld_stack_size; ++i) {
709 if (ref_buffer_stack->gld_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700710 is_free = 0;
711 break;
712 }
713 }
714
715 if (is_free) return idx;
716 }
717 return INVALID_IDX;
718}
719
Jingning Han42266ca2019-07-12 14:37:16 -0700720int av1_get_refresh_frame_flags(const AV1_COMP *const cpi,
721 const EncodeFrameParams *const frame_params,
722 FRAME_UPDATE_TYPE frame_update_type,
723 const RefBufferStack *const ref_buffer_stack) {
David Turner6e8b4d92019-02-18 15:01:33 +0000724 const AV1_COMMON *const cm = &cpi->common;
Vishesh38c05d72020-04-14 12:19:14 +0530725 const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
726 &cpi->ext_flags.refresh_frame;
727
Vishesha195ca32020-04-07 18:46:20 +0530728 const SVC *const svc = &cpi->svc;
David Turner6e8b4d92019-02-18 15:01:33 +0000729 // Switch frames and shown key-frames overwrite all reference slots
730 if ((frame_params->frame_type == KEY_FRAME && frame_params->show_frame) ||
731 frame_params->frame_type == S_FRAME)
732 return 0xFF;
733
734 // show_existing_frames don't actually send refresh_frame_flags so set the
735 // flags to 0 to keep things consistent.
David Turnere86ee0d2019-02-18 17:16:28 +0000736 if (frame_params->show_existing_frame &&
737 (!frame_params->error_resilient_mode ||
738 frame_params->frame_type == KEY_FRAME)) {
David Turner6e8b4d92019-02-18 15:01:33 +0000739 return 0;
740 }
741
Vishesh38c05d72020-04-14 12:19:14 +0530742 if (is_frame_droppable(svc, ext_refresh_frame_flags)) return 0;
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700743
David Turner6e8b4d92019-02-18 15:01:33 +0000744 int refresh_mask = 0;
745
Vishesh38c05d72020-04-14 12:19:14 +0530746 if (ext_refresh_frame_flags->update_pending) {
Vishesha195ca32020-04-07 18:46:20 +0530747 if (svc->external_ref_frame_config) {
Marco Paniconid8574e32019-08-04 21:30:12 -0700748 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
Vishesha195ca32020-04-07 18:46:20 +0530749 int ref_frame_map_idx = svc->ref_idx[i];
750 refresh_mask |= svc->refresh[ref_frame_map_idx] << ref_frame_map_idx;
Marco Paniconid8574e32019-08-04 21:30:12 -0700751 }
752 return refresh_mask;
753 }
David Turner6e8b4d92019-02-18 15:01:33 +0000754 // Unfortunately the encoder interface reflects the old refresh_*_frame
755 // flags so we have to replicate the old refresh_frame_flags logic here in
756 // order to preserve the behaviour of the flag overrides.
Marco Paniconi314bc362019-08-13 10:53:02 -0700757 int ref_frame_map_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
Jingning Han0a2af4e2019-07-08 19:30:03 -0700758 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530759 refresh_mask |= ext_refresh_frame_flags->last_frame << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700760
761 ref_frame_map_idx = get_ref_frame_map_idx(cm, EXTREF_FRAME);
762 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530763 refresh_mask |= ext_refresh_frame_flags->bwd_ref_frame
764 << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700765
766 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF2_FRAME);
767 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530768 refresh_mask |= ext_refresh_frame_flags->alt2_ref_frame
769 << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700770
David Turner6e8b4d92019-02-18 15:01:33 +0000771 if (frame_update_type == OVERLAY_UPDATE) {
Jingning Han5738e032019-07-22 15:22:52 -0700772 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
773 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530774 refresh_mask |= ext_refresh_frame_flags->golden_frame
775 << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000776 } else {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700777 ref_frame_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
778 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530779 refresh_mask |= ext_refresh_frame_flags->golden_frame
780 << ref_frame_map_idx;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700781
782 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
783 if (ref_frame_map_idx != INVALID_IDX)
Vishesh38c05d72020-04-14 12:19:14 +0530784 refresh_mask |= ext_refresh_frame_flags->alt_ref_frame
785 << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000786 }
787 return refresh_mask;
788 }
789
Jingning Hanc9c172d2019-07-23 14:10:32 -0700790 // Search for the open slot to store the current frame.
Jingning Han81d6fbb2019-07-15 10:14:13 -0700791 int free_fb_index = get_free_ref_map_index(ref_buffer_stack);
Jingning Han0a2af4e2019-07-08 19:30:03 -0700792 switch (frame_update_type) {
793 case KF_UPDATE:
794 case GF_UPDATE:
795 if (free_fb_index != INVALID_IDX) {
796 refresh_mask = 1 << free_fb_index;
797 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700798 if (ref_buffer_stack->gld_stack_size)
799 refresh_mask =
800 1 << ref_buffer_stack
801 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700802 else
Jingning Han42266ca2019-07-12 14:37:16 -0700803 refresh_mask =
804 1 << ref_buffer_stack
805 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700806 }
807 break;
808 case LF_UPDATE:
809 if (free_fb_index != INVALID_IDX) {
810 refresh_mask = 1 << free_fb_index;
811 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700812 if (ref_buffer_stack->lst_stack_size >= 2)
813 refresh_mask =
814 1 << ref_buffer_stack
815 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han1af1c012020-02-10 10:51:56 -0800816 else if (ref_buffer_stack->gld_stack_size >= 2)
817 refresh_mask =
818 1 << ref_buffer_stack
819 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700820 else
821 assert(0 && "No ref map index found");
822 }
823 break;
824 case ARF_UPDATE:
825 if (free_fb_index != INVALID_IDX) {
826 refresh_mask = 1 << free_fb_index;
827 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700828 if (ref_buffer_stack->gld_stack_size >= 3)
829 refresh_mask =
830 1 << ref_buffer_stack
831 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
832 else if (ref_buffer_stack->lst_stack_size >= 2)
833 refresh_mask =
834 1 << ref_buffer_stack
835 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700836 else
837 assert(0 && "No ref map index found");
838 }
839 break;
840 case INTNL_ARF_UPDATE:
841 if (free_fb_index != INVALID_IDX) {
842 refresh_mask = 1 << free_fb_index;
843 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700844 refresh_mask =
845 1 << ref_buffer_stack
846 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700847 }
848 break;
Jingning Han5738e032019-07-22 15:22:52 -0700849 case OVERLAY_UPDATE: break;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700850 case INTNL_OVERLAY_UPDATE: break;
851 default: assert(0); break;
852 }
853
854 return refresh_mask;
David Turner6e8b4d92019-02-18 15:01:33 +0000855}
856
Cheng Chen7abe3132019-06-19 11:55:28 -0700857#if !CONFIG_REALTIME_ONLY
Cheng Chen5083a9f2019-07-12 15:33:34 -0700858void setup_mi(AV1_COMP *const cpi, YV12_BUFFER_CONFIG *src) {
859 AV1_COMMON *const cm = &cpi->common;
860 const int num_planes = av1_num_planes(cm);
861 MACROBLOCK *const x = &cpi->td.mb;
862 MACROBLOCKD *const xd = &x->e_mbd;
863
864 av1_setup_src_planes(x, src, 0, 0, num_planes, cm->seq_params.sb_size);
865
866 av1_setup_block_planes(xd, cm->seq_params.subsampling_x,
867 cm->seq_params.subsampling_y, num_planes);
868
Urvang Joshi2603bfe2020-03-25 13:33:18 -0700869 set_mi_offsets(&cm->mi_params, xd, 0, 0);
Cheng Chen5083a9f2019-07-12 15:33:34 -0700870}
871
Cheng Chen7abe3132019-06-19 11:55:28 -0700872// Apply temporal filtering to key frames and encode the filtered frame.
873// If the current frame is not key frame, this function is identical to
874// av1_encode().
875static int denoise_and_encode(AV1_COMP *const cpi, uint8_t *const dest,
876 EncodeFrameInput *const frame_input,
877 EncodeFrameParams *const frame_params,
Hui Su028ad7d2020-04-13 23:24:32 -0700878 EncodeFrameResults *const frame_results) {
Cheng Chen7abe3132019-06-19 11:55:28 -0700879 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
880 AV1_COMMON *const cm = &cpi->common;
Jingning Han97b64a72019-10-08 11:40:51 -0700881
Hui Su028ad7d2020-04-13 23:24:32 -0700882 // Decide whether to apply temporal filtering to the source frame.
883 int apply_filtering =
884 frame_params->frame_type == KEY_FRAME &&
885 oxcf->enable_keyframe_filtering && !is_stat_generation_stage(cpi) &&
Sarah Parker21f1e6e2019-11-15 16:48:29 -0800886 !frame_params->show_existing_frame &&
yjshen0c942222020-01-23 13:55:46 -0800887 cpi->rc.frames_to_key > TF_NUM_FILTERING_FRAMES_FOR_KEY_FRAME &&
Hui Su028ad7d2020-04-13 23:24:32 -0700888 !is_lossless_requested(oxcf) && oxcf->arnr_max_frames > 0;
889 if (apply_filtering) {
890 const double y_noise_level = av1_estimate_noise_from_single_plane(
891 frame_input->source, 0, cm->seq_params.bit_depth);
892 apply_filtering = y_noise_level > 0;
893 }
894
Yunqing Wangce71fd72019-10-18 17:23:58 -0700895 // Save the pointer to the original source image.
896 YV12_BUFFER_CONFIG *source_kf_buffer = frame_input->source;
Cheng Chen7abe3132019-06-19 11:55:28 -0700897
Hui Su028ad7d2020-04-13 23:24:32 -0700898 // Apply filtering to key frame.
Cheng Chen7abe3132019-06-19 11:55:28 -0700899 if (apply_filtering) {
Cheng Chen5083a9f2019-07-12 15:33:34 -0700900 // Initialization for frame motion estimation.
901 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700902 av1_init_mi_buffers(&cm->mi_params);
Cheng Chen5083a9f2019-07-12 15:33:34 -0700903 setup_mi(cpi, frame_input->source);
Urvang Joshi9543ad72020-04-17 16:59:46 -0700904 av1_init_macroblockd(cm, xd);
Visheshd1317912020-04-07 14:39:44 +0530905 memset(
906 cpi->mbmi_ext_info.frame_base, 0,
907 cpi->mbmi_ext_info.alloc_size * sizeof(*cpi->mbmi_ext_info.frame_base));
Cheng Chen5083a9f2019-07-12 15:33:34 -0700908
909 av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
910 av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
911 av1_set_rd_speed_thresholds(cpi);
912 av1_setup_frame_buf_refs(cm);
913 av1_setup_frame_sign_bias(cm);
914 av1_frame_init_quantizer(cpi);
915 av1_setup_past_independence(cm);
916
Sarah Parker21f1e6e2019-11-15 16:48:29 -0800917 if (!frame_params->show_frame) {
918 int arf_src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
919 av1_temporal_filter(cpi, -1 * arf_src_index, NULL);
920 } else {
921 av1_temporal_filter(cpi, -1, NULL);
922 }
Hui Su028ad7d2020-04-13 23:24:32 -0700923 aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
Cheng Chen5083a9f2019-07-12 15:33:34 -0700924 // Use the filtered frame for encoding.
Cheng Chen7abe3132019-06-19 11:55:28 -0700925 frame_input->source = &cpi->alt_ref_buffer;
Akshata Jadhavc2098842019-11-26 16:16:29 +0530926 // Copy metadata info to alt-ref buffer.
927 aom_remove_metadata_from_frame_buffer(frame_input->source);
928 aom_copy_metadata_to_frame_buffer(frame_input->source,
929 source_kf_buffer->metadata);
Hui Sub1485372020-04-16 23:31:39 -0700930 }
Jingning Han97b64a72019-10-08 11:40:51 -0700931
Hui Sub1485372020-04-16 23:31:39 -0700932 if (frame_params->frame_type == KEY_FRAME && !is_stat_generation_stage(cpi) &&
933 oxcf->enable_tpl_model && oxcf->lag_in_frames > 0 &&
934 frame_params->show_frame) {
935 av1_tpl_setup_stats(cpi, 0, frame_params, frame_input);
Jingning Han97b64a72019-10-08 11:40:51 -0700936 }
937
938 if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
939 AOM_CODEC_OK) {
940 return AOM_CODEC_ERROR;
941 }
942
943 // Set frame_input source to true source for psnr calculation.
Hui Su028ad7d2020-04-13 23:24:32 -0700944 if (apply_filtering) {
Yunqing Wangce71fd72019-10-18 17:23:58 -0700945 cpi->source = source_kf_buffer;
946 cpi->unscaled_source = source_kf_buffer;
Jingning Han97b64a72019-10-08 11:40:51 -0700947 }
948
Cheng Chen7abe3132019-06-19 11:55:28 -0700949 return AOM_CODEC_OK;
950}
951#endif // !CONFIG_REALTIME_ONLY
952
Hui Su5f7ee812020-02-20 15:58:04 -0800953static INLINE int find_unused_ref_frame(const int *used_ref_frames,
954 const int *stack, int stack_size) {
955 for (int i = 0; i < stack_size; ++i) {
956 const int this_ref = stack[i];
957 int ref_idx = 0;
958 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx) {
959 if (this_ref == used_ref_frames[ref_idx]) break;
960 }
961
962 // not in use
963 if (ref_idx > ALTREF_FRAME - LAST_FRAME) return this_ref;
964 }
965
966 return INVALID_IDX;
967}
968
Jingning Handae645a2019-08-01 10:00:11 -0700969void av1_get_ref_frames(AV1_COMP *const cpi, RefBufferStack *ref_buffer_stack) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700970 AV1_COMMON *cm = &cpi->common;
Hui Su5f7ee812020-02-20 15:58:04 -0800971 int *const remapped_ref_idx = cm->remapped_ref_idx;
972 int *const arf_stack = ref_buffer_stack->arf_stack;
973 int *const lst_stack = ref_buffer_stack->lst_stack;
974 int *const gld_stack = ref_buffer_stack->gld_stack;
Jingning Han42266ca2019-07-12 14:37:16 -0700975 const int arf_stack_size = ref_buffer_stack->arf_stack_size;
976 const int lst_stack_size = ref_buffer_stack->lst_stack_size;
977 const int gld_stack_size = ref_buffer_stack->gld_stack_size;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700978
979 // Initialization
Hui Su5f7ee812020-02-20 15:58:04 -0800980 for (int i = 0; i < REF_FRAMES; ++i) remapped_ref_idx[i] = INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700981
982 if (arf_stack_size) {
Hui Su5f7ee812020-02-20 15:58:04 -0800983 remapped_ref_idx[ALTREF_FRAME - LAST_FRAME] = arf_stack[arf_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700984
985 if (arf_stack_size > 1)
Hui Su5f7ee812020-02-20 15:58:04 -0800986 remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = arf_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700987
988 if (arf_stack_size > 2)
Hui Su5f7ee812020-02-20 15:58:04 -0800989 remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] = arf_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700990 }
991
992 if (lst_stack_size) {
Hui Su5f7ee812020-02-20 15:58:04 -0800993 remapped_ref_idx[LAST_FRAME - LAST_FRAME] = lst_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700994
995 if (lst_stack_size > 1)
Hui Su5f7ee812020-02-20 15:58:04 -0800996 remapped_ref_idx[LAST2_FRAME - LAST_FRAME] = lst_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700997 }
998
999 if (gld_stack_size) {
Hui Su5f7ee812020-02-20 15:58:04 -08001000 remapped_ref_idx[GOLDEN_FRAME - LAST_FRAME] = gld_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001001
Hui Su483d25d2020-04-15 00:28:08 -07001002 // If there are more frames in the golden stack, assign them to BWDREF,
1003 // ALTREF2, or LAST3.
Jingning Han0a2af4e2019-07-08 19:30:03 -07001004 if (gld_stack_size > 1) {
Hui Su483d25d2020-04-15 00:28:08 -07001005 if (arf_stack_size <= 2) {
1006 if (arf_stack_size <= 1) {
1007 remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = gld_stack[1];
1008 if (gld_stack_size > 2)
1009 remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] = gld_stack[2];
1010 } else {
1011 remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] = gld_stack[1];
1012 }
1013 } else {
Hui Su5f7ee812020-02-20 15:58:04 -08001014 remapped_ref_idx[LAST3_FRAME - LAST_FRAME] = gld_stack[1];
Hui Su483d25d2020-04-15 00:28:08 -07001015 }
Jingning Han0a2af4e2019-07-08 19:30:03 -07001016 }
1017 }
1018
1019 for (int idx = ALTREF_FRAME - LAST_FRAME; idx >= 0; --idx) {
Hui Su5f7ee812020-02-20 15:58:04 -08001020 int ref_map_index = remapped_ref_idx[idx];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001021
1022 if (ref_map_index != INVALID_IDX) continue;
1023
Hui Su5f7ee812020-02-20 15:58:04 -08001024 ref_map_index =
1025 find_unused_ref_frame(remapped_ref_idx, arf_stack, arf_stack_size);
Jingning Han0a2af4e2019-07-08 19:30:03 -07001026
Hui Su5f7ee812020-02-20 15:58:04 -08001027 if (ref_map_index == INVALID_IDX) {
1028 ref_map_index =
1029 find_unused_ref_frame(remapped_ref_idx, gld_stack, gld_stack_size);
Jingning Han0a2af4e2019-07-08 19:30:03 -07001030 }
1031
Hui Su5f7ee812020-02-20 15:58:04 -08001032 if (ref_map_index == INVALID_IDX) {
1033 ref_map_index =
1034 find_unused_ref_frame(remapped_ref_idx, lst_stack, lst_stack_size);
Jingning Han0a2af4e2019-07-08 19:30:03 -07001035 }
1036
1037 if (ref_map_index != INVALID_IDX)
Hui Su5f7ee812020-02-20 15:58:04 -08001038 remapped_ref_idx[idx] = ref_map_index;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001039 else
Hui Su5f7ee812020-02-20 15:58:04 -08001040 remapped_ref_idx[idx] = ref_buffer_stack->gld_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001041 }
1042}
1043
David Turner056f7cd2019-01-07 17:48:13 +00001044int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
David Turner1539bb02019-01-24 15:28:13 +00001045 uint8_t *const dest, unsigned int *frame_flags,
David Turnerdedd8ff2019-01-23 13:59:46 +00001046 int64_t *const time_stamp, int64_t *const time_end,
Yue Chen1bc5be62018-08-24 13:57:32 -07001047 const aom_rational64_t *const timestamp_ratio,
1048 int flush) {
David Turner1539bb02019-01-24 15:28:13 +00001049 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
David Turner475a3132019-01-18 15:17:17 +00001050 AV1_COMMON *const cm = &cpi->common;
Jingning Hana7293932019-08-15 15:46:49 -07001051 GF_GROUP *gf_group = &cpi->gf_group;
Vishesha195ca32020-04-07 18:46:20 +05301052 ExternalFlags *const ext_flags = &cpi->ext_flags;
David Turner056f7cd2019-01-07 17:48:13 +00001053
David Turnerdedd8ff2019-01-23 13:59:46 +00001054 EncodeFrameInput frame_input;
David Turner04b70d82019-01-24 15:39:19 +00001055 EncodeFrameParams frame_params;
1056 EncodeFrameResults frame_results;
David Turnerdedd8ff2019-01-23 13:59:46 +00001057 memset(&frame_input, 0, sizeof(frame_input));
David Turner04b70d82019-01-24 15:39:19 +00001058 memset(&frame_params, 0, sizeof(frame_params));
1059 memset(&frame_results, 0, sizeof(frame_results));
1060
Sarah Parker97803fc2019-05-17 14:15:37 -07001061 // TODO(sarahparker) finish bit allocation for one pass pyramid
Urvang Joshib44f48f2020-01-27 11:09:48 -08001062 if (has_no_stats_stage(cpi) && oxcf->rc_mode != AOM_Q) {
1063 cpi->oxcf.gf_max_pyr_height =
1064 AOMMIN(cpi->oxcf.gf_max_pyr_height, USE_ALTREF_FOR_ONE_PASS);
1065 cpi->oxcf.gf_min_pyr_height =
1066 AOMMIN(cpi->oxcf.gf_min_pyr_height, cpi->oxcf.gf_max_pyr_height);
1067 }
Sarah Parker97803fc2019-05-17 14:15:37 -07001068
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301069 if (!is_stat_generation_stage(cpi)) {
Sarah Parker2beb1d12019-10-25 16:30:32 -07001070 // If this is a forward keyframe, mark as a show_existing_frame
1071 if (cpi->oxcf.fwd_kf_enabled && (gf_group->index == gf_group->size) &&
1072 gf_group->update_type[1] == ARF_UPDATE && cpi->rc.frames_to_key == 0) {
1073 frame_params.show_existing_frame = 1;
1074 } else {
1075 frame_params.show_existing_frame =
chiyotsai6b430132019-12-18 10:33:51 -08001076 ((oxcf->enable_overlay == 0 || cpi->sf.hl_sf.disable_overlay_frames ||
Sarah Parker2beb1d12019-10-25 16:30:32 -07001077 cpi->show_existing_alt_ref) &&
1078 gf_group->update_type[gf_group->index] == OVERLAY_UPDATE) ||
1079 gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE;
1080 }
David Turnere86ee0d2019-02-18 17:16:28 +00001081 frame_params.show_existing_frame &= allow_show_existing(cpi, *frame_flags);
Yunqing Wang1973f112019-10-18 15:50:04 -07001082
1083 // Reset show_existing_alt_ref decision to 0 after it is used.
1084 if (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE) {
1085 cpi->show_existing_alt_ref = 0;
1086 }
David Turnerb0c0aa32019-01-28 16:17:13 +00001087 } else {
David Turnere86ee0d2019-02-18 17:16:28 +00001088 frame_params.show_existing_frame = 0;
David Turnerb0c0aa32019-01-28 16:17:13 +00001089 }
1090
Jingning Hanbb782982019-08-15 11:28:46 -07001091 int code_arf = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +00001092 struct lookahead_entry *source = NULL;
1093 struct lookahead_entry *last_source = NULL;
David Turnere86ee0d2019-02-18 17:16:28 +00001094 if (frame_params.show_existing_frame) {
Mufaddal Chakeraac828682019-12-13 16:31:42 +05301095 source = av1_lookahead_pop(cpi->lookahead, flush, cpi->compressor_stage);
Jingning Hand392c012019-09-19 15:48:08 -07001096 frame_params.show_frame = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +00001097 } else {
Yunqing Wang699fa7f2019-10-15 17:40:46 -07001098 int show_existing_alt_ref = 0;
Jingning Hanbb782982019-08-15 11:28:46 -07001099 source = choose_frame_source(cpi, &code_arf, &flush, &last_source,
Yunqing Wang699fa7f2019-10-15 17:40:46 -07001100 &frame_params, &show_existing_alt_ref);
Yunqing Wang1973f112019-10-18 15:50:04 -07001101 if (gf_group->update_type[gf_group->index] == ARF_UPDATE)
1102 cpi->show_existing_alt_ref = show_existing_alt_ref;
David Turnerdedd8ff2019-01-23 13:59:46 +00001103 }
1104
1105 if (source == NULL) { // If no source was found, we can't encode a frame.
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001106#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +00001107 if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
1108 av1_end_first_pass(cpi); /* get last stats packet */
1109 cpi->twopass.first_pass_done = 1;
1110 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001111#endif
David Turnerdedd8ff2019-01-23 13:59:46 +00001112 return -1;
1113 }
1114
Jingning Hanbb782982019-08-15 11:28:46 -07001115 frame_input.source = code_arf ? &cpi->alt_ref_buffer : &source->img;
David Turnerdedd8ff2019-01-23 13:59:46 +00001116 frame_input.last_source = last_source != NULL ? &last_source->img : NULL;
1117 frame_input.ts_duration = source->ts_end - source->ts_start;
Cheng Chene1a7a3e2020-03-18 18:23:19 -07001118 // Save unfiltered source. It is used in av1_get_second_pass_params().
1119 cpi->unfiltered_source = frame_input.source;
David Turnerdedd8ff2019-01-23 13:59:46 +00001120
1121 *time_stamp = source->ts_start;
1122 *time_end = source->ts_end;
Deepa K Gfb89ce02020-04-06 13:34:42 +05301123 if (source->ts_start < cpi->time_stamps.first_ever) {
1124 cpi->time_stamps.first_ever = source->ts_start;
1125 cpi->time_stamps.prev_end_seen = source->ts_start;
David Turnerdedd8ff2019-01-23 13:59:46 +00001126 }
1127
1128 av1_apply_encoding_flags(cpi, source->flags);
David Turnere86ee0d2019-02-18 17:16:28 +00001129 if (!frame_params.show_existing_frame)
David Turnerdedd8ff2019-01-23 13:59:46 +00001130 *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
David Turnerdedd8ff2019-01-23 13:59:46 +00001131
Jingning Hand392c012019-09-19 15:48:08 -07001132 // Shown frames and arf-overlay frames need frame-rate considering
Deepa K Gfb89ce02020-04-06 13:34:42 +05301133 if (frame_params.show_frame)
1134 adjust_frame_rate(cpi, source->ts_start, source->ts_end);
David Turnerdedd8ff2019-01-23 13:59:46 +00001135
Jingning Hand392c012019-09-19 15:48:08 -07001136 if (!frame_params.show_existing_frame) {
David Turnerdedd8ff2019-01-23 13:59:46 +00001137 if (cpi->film_grain_table) {
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001138 cm->cur_frame->film_grain_params_present = aom_film_grain_table_lookup(
David Turnerdedd8ff2019-01-23 13:59:46 +00001139 cpi->film_grain_table, *time_stamp, *time_end, 0 /* =erase */,
1140 &cm->film_grain_params);
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001141 } else {
1142 cm->cur_frame->film_grain_params_present =
1143 cm->seq_params.film_grain_params_present;
David Turnerdedd8ff2019-01-23 13:59:46 +00001144 }
David Turnerdedd8ff2019-01-23 13:59:46 +00001145 // only one operating point supported now
Yue Chen1bc5be62018-08-24 13:57:32 -07001146 const int64_t pts64 = ticks_to_timebase_units(timestamp_ratio, *time_stamp);
David Turnerdedd8ff2019-01-23 13:59:46 +00001147 if (pts64 < 0 || pts64 > UINT32_MAX) return AOM_CODEC_ERROR;
Jingning Hand392c012019-09-19 15:48:08 -07001148 cm->frame_presentation_time = (uint32_t)pts64;
David Turnerdedd8ff2019-01-23 13:59:46 +00001149 }
1150
Marco Paniconicea99e22019-07-16 18:36:31 -07001151#if CONFIG_REALTIME_ONLY
1152 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
Marco Paniconicea99e22019-07-16 18:36:31 -07001153#else
Mufaddal Chakera3bcc72c2019-12-11 14:38:37 +05301154 if (has_no_stats_stage(cpi) && oxcf->mode == REALTIME &&
1155 oxcf->lag_in_frames == 0)
Marco Paniconicea99e22019-07-16 18:36:31 -07001156 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301157 else if (!is_stat_generation_stage(cpi))
Jingning Han491198d2020-02-13 21:53:41 -08001158 av1_get_second_pass_params(cpi, &frame_params, &frame_input, *frame_flags);
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001159#endif
Jingning Hand392c012019-09-19 15:48:08 -07001160 FRAME_UPDATE_TYPE frame_update_type = get_frame_update_type(gf_group);
David Turner4f1f1812019-01-24 17:00:24 +00001161
David Turnere86ee0d2019-02-18 17:16:28 +00001162 if (frame_params.show_existing_frame &&
1163 frame_params.frame_type != KEY_FRAME) {
David Turner475a3132019-01-18 15:17:17 +00001164 // Force show-existing frames to be INTER, except forward keyframes
1165 frame_params.frame_type = INTER_FRAME;
1166 }
1167
David Turner056f7cd2019-01-07 17:48:13 +00001168 // TODO(david.turner@argondesign.com): Move all the encode strategy
1169 // (largely near av1_get_compressed_data) in here
1170
1171 // TODO(david.turner@argondesign.com): Change all the encode strategy to
1172 // modify frame_params instead of cm or cpi.
1173
David Turner04b70d82019-01-24 15:39:19 +00001174 // Per-frame encode speed. In theory this can vary, but things may have been
1175 // written assuming speed-level will not change within a sequence, so this
1176 // parameter should be used with caution.
1177 frame_params.speed = oxcf->speed;
1178
David Turnerddbff442019-01-21 14:58:42 +00001179 // Work out some encoding parameters specific to the pass:
Mufaddal Chakera3bcc72c2019-12-11 14:38:37 +05301180 if (has_no_stats_stage(cpi) && cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Sarah Parker97803fc2019-05-17 14:15:37 -07001181 av1_cyclic_refresh_update_parameters(cpi);
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301182 } else if (is_stat_generation_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001183 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&cpi->oxcf);
David Turner4f1f1812019-01-24 17:00:24 +00001184 const int kf_requested = (cm->current_frame.frame_number == 0 ||
David Turner73245762019-02-11 16:42:34 +00001185 (*frame_flags & FRAMEFLAGS_KEY));
David Turner4f1f1812019-01-24 17:00:24 +00001186 if (kf_requested && frame_update_type != OVERLAY_UPDATE &&
1187 frame_update_type != INTNL_OVERLAY_UPDATE) {
David Turnerddbff442019-01-21 14:58:42 +00001188 frame_params.frame_type = KEY_FRAME;
1189 } else {
1190 frame_params.frame_type = INTER_FRAME;
David Turnercb5e36f2019-01-17 17:15:25 +00001191 }
Hamsalekha S37cc1d12019-12-12 19:27:41 +05301192 } else if (is_stat_consumption_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001193#if CONFIG_MISMATCH_DEBUG
1194 mismatch_move_frame_idx_w();
1195#endif
1196#if TXCOEFF_COST_TIMER
1197 cm->txcoeff_cost_timer = 0;
1198 cm->txcoeff_cost_count = 0;
1199#endif
1200 }
1201
Vishesha195ca32020-04-07 18:46:20 +05301202 if (!is_stat_generation_stage(cpi))
1203 set_ext_overrides(cm, &frame_params, ext_flags);
David Turnerddbff442019-01-21 14:58:42 +00001204
David Turner4f1f1812019-01-24 17:00:24 +00001205 // Shown keyframes and S frames refresh all reference buffers
1206 const int force_refresh_all =
1207 ((frame_params.frame_type == KEY_FRAME && frame_params.show_frame) ||
1208 frame_params.frame_type == S_FRAME) &&
David Turnere86ee0d2019-02-18 17:16:28 +00001209 !frame_params.show_existing_frame;
David Turner4f1f1812019-01-24 17:00:24 +00001210
Jayasanker J24cb9bc2020-04-15 13:43:10 +05301211 av1_configure_buffer_updates(cpi, &frame_params.refresh_frame,
1212 frame_update_type, force_refresh_all);
David Turner4f1f1812019-01-24 17:00:24 +00001213
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301214 if (!is_stat_generation_stage(cpi)) {
Deepa K G140bc832019-10-30 17:16:29 +05301215 const RefCntBuffer *ref_frames[INTER_REFS_PER_FRAME];
1216 const YV12_BUFFER_CONFIG *ref_frame_buf[INTER_REFS_PER_FRAME];
1217
Vishesh38c05d72020-04-14 12:19:14 +05301218 if (!ext_flags->refresh_frame.update_pending) {
Jingning Handae645a2019-08-01 10:00:11 -07001219 av1_get_ref_frames(cpi, &cpi->ref_buffer_stack);
Marco Paniconid8574e32019-08-04 21:30:12 -07001220 } else if (cpi->svc.external_ref_frame_config) {
Marco Paniconi67142112019-07-24 15:00:31 -07001221 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++)
1222 cm->remapped_ref_idx[i] = cpi->svc.ref_idx[i];
1223 }
Jingning Han0a2af4e2019-07-08 19:30:03 -07001224
Deepa K G140bc832019-10-30 17:16:29 +05301225 // Get the reference frames
1226 for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
1227 ref_frames[i] = get_ref_frame_buf(cm, ref_frame_priority_order[i]);
1228 ref_frame_buf[i] = ref_frames[i] != NULL ? &ref_frames[i]->buf : NULL;
1229 }
David Turnerddbff442019-01-21 14:58:42 +00001230 // Work out which reference frame slots may be used.
Vishesha195ca32020-04-07 18:46:20 +05301231 frame_params.ref_frame_flags = get_ref_frame_flags(
1232 &cpi->sf, ref_frame_buf, ext_flags->ref_frame_flags);
David Turnerddbff442019-01-21 14:58:42 +00001233
David Turnera7f133c2019-01-22 14:47:16 +00001234 frame_params.primary_ref_frame =
1235 choose_primary_ref_frame(cpi, &frame_params);
Sarah Parkere1b22012019-06-06 16:35:25 -07001236 frame_params.order_offset = get_order_offset(&cpi->gf_group, &frame_params);
David Turner6e8b4d92019-02-18 15:01:33 +00001237
Jingning Han42266ca2019-07-12 14:37:16 -07001238 frame_params.refresh_frame_flags = av1_get_refresh_frame_flags(
1239 cpi, &frame_params, frame_update_type, &cpi->ref_buffer_stack);
Jingning Hana7293932019-08-15 15:46:49 -07001240
1241 frame_params.existing_fb_idx_to_show =
1242 frame_params.show_existing_frame
Debargha Mukherjeea2074dd2019-09-04 10:03:44 -07001243 ? (frame_update_type == INTNL_OVERLAY_UPDATE
1244 ? get_ref_frame_map_idx(cm, BWDREF_FRAME)
1245 : get_ref_frame_map_idx(cm, ALTREF_FRAME))
Jingning Hana7293932019-08-15 15:46:49 -07001246 : INVALID_IDX;
David Turnera7f133c2019-01-22 14:47:16 +00001247 }
1248
David Turner73245762019-02-11 16:42:34 +00001249 // The way frame_params->remapped_ref_idx is setup is a placeholder.
David Turnerf4592292019-02-21 11:50:30 +00001250 // Currently, reference buffer assignment is done by update_ref_frame_map()
David Turner73245762019-02-11 16:42:34 +00001251 // which is called by high-level strategy AFTER encoding a frame. It modifies
1252 // cm->remapped_ref_idx. If you want to use an alternative method to
1253 // determine reference buffer assignment, just put your assignments into
1254 // frame_params->remapped_ref_idx here and they will be used when encoding
1255 // this frame. If frame_params->remapped_ref_idx is setup independently of
David Turnerf4592292019-02-21 11:50:30 +00001256 // cm->remapped_ref_idx then update_ref_frame_map() will have no effect.
David Turner73245762019-02-11 16:42:34 +00001257 memcpy(frame_params.remapped_ref_idx, cm->remapped_ref_idx,
1258 REF_FRAMES * sizeof(*cm->remapped_ref_idx));
1259
Ravi Chaudharyeeae7292019-06-26 13:32:59 +05301260 cpi->td.mb.e_mbd.delta_qindex = 0;
Yue Chen4e585cc2019-06-03 14:47:16 -07001261
1262 if (!frame_params.show_existing_frame) {
Urvang Joshi17814622020-03-27 17:26:17 -07001263 cm->quant_params.using_qmatrix = cpi->oxcf.using_qm;
Jerome Jiangd413f4a2019-09-23 14:53:03 -07001264#if !CONFIG_REALTIME_ONLY
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301265 if (oxcf->lag_in_frames > 0 && !is_stat_generation_stage(cpi)) {
Sarah Parkere1b22012019-06-06 16:35:25 -07001266 if (cpi->gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
Jayasanker J24cb9bc2020-04-15 13:43:10 +05301267 av1_configure_buffer_updates(cpi, &frame_params.refresh_frame,
1268 frame_update_type, 0);
Yue Chen4e585cc2019-06-03 14:47:16 -07001269 av1_set_frame_size(cpi, cm->width, cm->height);
Jingning Han491198d2020-02-13 21:53:41 -08001270 av1_tpl_setup_stats(cpi, 0, &frame_params, &frame_input);
Yue Chen4e585cc2019-06-03 14:47:16 -07001271 assert(cpi->num_gf_group_show_frames == 1);
1272 }
1273 }
Jerome Jiangd413f4a2019-09-23 14:53:03 -07001274#endif
Yue Chen4e585cc2019-06-03 14:47:16 -07001275 }
1276
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001277#if CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +00001278 if (av1_encode(cpi, dest, &frame_input, &frame_params, &frame_results) !=
David Turnerddbff442019-01-21 14:58:42 +00001279 AOM_CODEC_OK) {
1280 return AOM_CODEC_ERROR;
1281 }
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001282#else
Hui Su028ad7d2020-04-13 23:24:32 -07001283 if (denoise_and_encode(cpi, dest, &frame_input, &frame_params,
1284 &frame_results) != AOM_CODEC_OK) {
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001285 return AOM_CODEC_ERROR;
1286 }
1287#endif // CONFIG_REALTIME_ONLY
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301288 if (!is_stat_generation_stage(cpi))
1289 cpi->num_gf_group_show_frames += frame_params.show_frame;
David Turnerddbff442019-01-21 14:58:42 +00001290
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301291 if (!is_stat_generation_stage(cpi)) {
David Turner73245762019-02-11 16:42:34 +00001292 // First pass doesn't modify reference buffer assignment or produce frame
1293 // flags
Jayasanker J24cb9bc2020-04-15 13:43:10 +05301294 update_frame_flags(&cpi->common, &cpi->refresh_frame, frame_flags);
Vishesh38c05d72020-04-14 12:19:14 +05301295 if (!ext_flags->refresh_frame.update_pending) {
Marco Paniconi8d335b72019-08-06 09:07:07 -07001296 int ref_map_index =
1297 av1_get_refresh_ref_frame_map(cm->current_frame.refresh_frame_flags);
Sarah Parkeredffc652019-10-25 16:30:32 -07001298 av1_update_ref_frame_map(cpi, frame_update_type, cm->show_existing_frame,
1299 ref_map_index, &cpi->ref_buffer_stack);
Marco Paniconi8d335b72019-08-06 09:07:07 -07001300 }
David Turner73245762019-02-11 16:42:34 +00001301 }
1302
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001303#if !CONFIG_REALTIME_ONLY
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301304 if (!is_stat_generation_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001305#if TXCOEFF_COST_TIMER
1306 cm->cum_txcoeff_cost_timer += cm->txcoeff_cost_timer;
1307 fprintf(stderr,
1308 "\ntxb coeff cost block number: %ld, frame time: %ld, cum time %ld "
1309 "in us\n",
1310 cm->txcoeff_cost_count, cm->txcoeff_cost_timer,
1311 cm->cum_txcoeff_cost_timer);
1312#endif
1313 av1_twopass_postencode_update(cpi);
1314 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001315#endif // !CONFIG_REALTIME_ONLY
David Turnerddbff442019-01-21 14:58:42 +00001316
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301317 if (!is_stat_generation_stage(cpi)) {
David Turnera7f133c2019-01-22 14:47:16 +00001318 update_fb_of_context_type(cpi, &frame_params, cpi->fb_of_context_type);
David Turner73245762019-02-11 16:42:34 +00001319 set_additional_frame_flags(cm, frame_flags);
David Turnerddbff442019-01-21 14:58:42 +00001320 update_rc_counts(cpi);
David Turner056f7cd2019-01-07 17:48:13 +00001321 }
1322
David Turner1539bb02019-01-24 15:28:13 +00001323 // Unpack frame_results:
David Turner056f7cd2019-01-07 17:48:13 +00001324 *size = frame_results.size;
1325
David Turner1539bb02019-01-24 15:28:13 +00001326 // Leave a signal for a higher level caller about if this frame is droppable
1327 if (*size > 0) {
Vishesh38c05d72020-04-14 12:19:14 +05301328 cpi->droppable = is_frame_droppable(&cpi->svc, &ext_flags->refresh_frame);
David Turner1539bb02019-01-24 15:28:13 +00001329 }
1330
Marco Paniconi5b1e4732019-08-08 18:57:53 -07001331 if (cpi->use_svc) av1_save_layer_context(cpi);
1332
David Turner056f7cd2019-01-07 17:48:13 +00001333 return AOM_CODEC_OK;
1334}