blob: 54d26a12ba87d1c34da9448dd31d72abddd3399e [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
David Turner07dbd8e2019-01-08 17:16:25 +000026#include "av1/common/onyxc_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
Yaowu Xu1afe7c42019-02-03 15:07:32 -080039void av1_configure_buffer_updates(AV1_COMP *const cpi,
David Turnerfe3aecb2019-02-06 14:42:42 +000040 EncodeFrameParams *const frame_params,
David Turner4f1f1812019-01-24 17:00:24 +000041 const FRAME_UPDATE_TYPE type,
42 int force_refresh_all) {
David Turnerce9b5902019-01-23 17:25:47 +000043 // NOTE(weitinglin): Should we define another function to take care of
44 // cpi->rc.is_$Source_Type to make this function as it is in the comment?
45
David Turner4f1f1812019-01-24 17:00:24 +000046 cpi->rc.is_src_frame_alt_ref = 0;
David Turnerce9b5902019-01-23 17:25:47 +000047
48 switch (type) {
49 case KF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000050 frame_params->refresh_last_frame = 1;
51 frame_params->refresh_golden_frame = 1;
52 frame_params->refresh_bwd_ref_frame = 1;
David Turnerfe3aecb2019-02-06 14:42:42 +000053 frame_params->refresh_alt_ref_frame = 1;
David Turnerce9b5902019-01-23 17:25:47 +000054 break;
55
56 case LF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000057 frame_params->refresh_last_frame = 1;
58 frame_params->refresh_golden_frame = 0;
59 frame_params->refresh_bwd_ref_frame = 0;
David Turnerfe3aecb2019-02-06 14:42:42 +000060 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000061 break;
62
63 case GF_UPDATE:
Jingning Hana9bb6672019-08-14 12:49:12 -070064 frame_params->refresh_last_frame = 0;
David Turnerfe3aecb2019-02-06 14:42:42 +000065 frame_params->refresh_golden_frame = 1;
66 frame_params->refresh_bwd_ref_frame = 0;
David Turnerfe3aecb2019-02-06 14:42:42 +000067 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000068 break;
69
70 case OVERLAY_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000071 frame_params->refresh_last_frame = 0;
72 frame_params->refresh_golden_frame = 1;
73 frame_params->refresh_bwd_ref_frame = 0;
David Turnerfe3aecb2019-02-06 14:42:42 +000074 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000075
76 cpi->rc.is_src_frame_alt_ref = 1;
77 break;
78
79 case ARF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000080 frame_params->refresh_last_frame = 0;
81 frame_params->refresh_golden_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000082 // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
David Turnerfe3aecb2019-02-06 14:42:42 +000083 frame_params->refresh_bwd_ref_frame = 0;
David Turnerfe3aecb2019-02-06 14:42:42 +000084 frame_params->refresh_alt_ref_frame = 1;
David Turnerce9b5902019-01-23 17:25:47 +000085 break;
86
David Turnerce9b5902019-01-23 17:25:47 +000087 case INTNL_OVERLAY_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000088 frame_params->refresh_last_frame = 1;
89 frame_params->refresh_golden_frame = 0;
90 frame_params->refresh_bwd_ref_frame = 0;
David Turnerfe3aecb2019-02-06 14:42:42 +000091 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000092
93 cpi->rc.is_src_frame_alt_ref = 1;
David Turnerce9b5902019-01-23 17:25:47 +000094 break;
95
96 case INTNL_ARF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000097 frame_params->refresh_last_frame = 0;
98 frame_params->refresh_golden_frame = 0;
Jingning Han591e51c2019-08-13 11:19:57 -070099 frame_params->refresh_bwd_ref_frame = 1;
David Turnerfe3aecb2019-02-06 14:42:42 +0000100 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +0000101 break;
102
103 default: assert(0); break;
104 }
David Turner4f1f1812019-01-24 17:00:24 +0000105
106 if (cpi->ext_refresh_frame_flags_pending &&
Mufaddal Chakerae7326122019-12-04 14:49:09 +0530107 (!is_stat_generation_stage(cpi))) {
David Turnerfe3aecb2019-02-06 14:42:42 +0000108 frame_params->refresh_last_frame = cpi->ext_refresh_last_frame;
109 frame_params->refresh_golden_frame = cpi->ext_refresh_golden_frame;
110 frame_params->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
111 frame_params->refresh_bwd_ref_frame = cpi->ext_refresh_bwd_ref_frame;
David Turner4f1f1812019-01-24 17:00:24 +0000112 }
113
114 if (force_refresh_all) {
David Turnerfe3aecb2019-02-06 14:42:42 +0000115 frame_params->refresh_last_frame = 1;
116 frame_params->refresh_golden_frame = 1;
117 frame_params->refresh_bwd_ref_frame = 1;
David Turnerfe3aecb2019-02-06 14:42:42 +0000118 frame_params->refresh_alt_ref_frame = 1;
David Turner4f1f1812019-01-24 17:00:24 +0000119 }
David Turnerce9b5902019-01-23 17:25:47 +0000120}
121
David Turner1539bb02019-01-24 15:28:13 +0000122static void set_additional_frame_flags(const AV1_COMMON *const cm,
123 unsigned int *const frame_flags) {
124 if (frame_is_intra_only(cm)) *frame_flags |= FRAMEFLAGS_INTRAONLY;
125 if (frame_is_sframe(cm)) *frame_flags |= FRAMEFLAGS_SWITCH;
126 if (cm->error_resilient_mode) *frame_flags |= FRAMEFLAGS_ERROR_RESILIENT;
127}
128
129static INLINE void update_keyframe_counters(AV1_COMP *cpi) {
Urvang Joshi6ce7fbc2019-03-22 15:24:21 -0700130 if (cpi->common.show_frame) {
David Turner1539bb02019-01-24 15:28:13 +0000131 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref ||
132 cpi->common.current_frame.frame_type == KEY_FRAME) {
133 // If this is a show_existing_frame with a source other than altref,
134 // or if it is not a displayed forward keyframe, the keyframe update
135 // counters were incremented when it was originally encoded.
136 cpi->rc.frames_since_key++;
137 cpi->rc.frames_to_key--;
138 }
139 }
140}
141
142static INLINE int is_frame_droppable(const AV1_COMP *const cpi) {
Jingning Han98d20de2019-08-14 12:59:47 -0700143 // Droppable frame is only used by external refresh flags. VoD setting won't
144 // trigger its use case.
Marco Paniconid8574e32019-08-04 21:30:12 -0700145 if (cpi->svc.external_ref_frame_config)
146 return cpi->svc.non_reference_frame;
147 else if (cpi->ext_refresh_frame_flags_pending)
Marco Paniconi91a50022019-08-01 18:56:39 -0700148 return !(cpi->ext_refresh_alt_ref_frame ||
149 cpi->ext_refresh_alt2_ref_frame ||
150 cpi->ext_refresh_bwd_ref_frame || cpi->ext_refresh_golden_frame ||
151 cpi->ext_refresh_last_frame);
152 else
Jingning Han98d20de2019-08-14 12:59:47 -0700153 return 0;
David Turner1539bb02019-01-24 15:28:13 +0000154}
155
156static INLINE void update_frames_till_gf_update(AV1_COMP *cpi) {
157 // TODO(weitinglin): Updating this counter for is_frame_droppable
158 // is a work-around to handle the condition when a frame is drop.
159 // We should fix the cpi->common.show_frame flag
160 // instead of checking the other condition to update the counter properly.
161 if (cpi->common.show_frame || is_frame_droppable(cpi)) {
162 // Decrement count down till next gf
163 if (cpi->rc.frames_till_gf_update_due > 0)
164 cpi->rc.frames_till_gf_update_due--;
165 }
166}
167
Sarah Parker97803fc2019-05-17 14:15:37 -0700168static INLINE void update_gf_group_index(AV1_COMP *cpi) {
David Turner1539bb02019-01-24 15:28:13 +0000169 // Increment the gf group index ready for the next frame. If this is
170 // a show_existing_frame with a source other than altref, or if it is not
171 // a displayed forward keyframe, the index was incremented when it was
172 // originally encoded.
173 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref ||
174 cpi->common.current_frame.frame_type == KEY_FRAME) {
Sarah Parkere1b22012019-06-06 16:35:25 -0700175 ++cpi->gf_group.index;
David Turner1539bb02019-01-24 15:28:13 +0000176 }
177}
178
179static void update_rc_counts(AV1_COMP *cpi) {
180 update_keyframe_counters(cpi);
181 update_frames_till_gf_update(cpi);
Sarah Parker97803fc2019-05-17 14:15:37 -0700182 update_gf_group_index(cpi);
David Turner1539bb02019-01-24 15:28:13 +0000183}
184
David Turner07dbd8e2019-01-08 17:16:25 +0000185static void set_ext_overrides(AV1_COMP *const cpi,
186 EncodeFrameParams *const frame_params) {
187 // Overrides the defaults with the externally supplied values with
188 // av1_update_reference() and av1_update_entropy() calls
189 // Note: The overrides are valid only for the next frame passed
190 // to av1_encode_lowlevel()
191
192 AV1_COMMON *const cm = &cpi->common;
193
194 if (cpi->ext_use_s_frame) {
David Turner475a3132019-01-18 15:17:17 +0000195 frame_params->frame_type = S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000196 }
David Turner07dbd8e2019-01-08 17:16:25 +0000197
198 if (cpi->ext_refresh_frame_context_pending) {
199 cm->refresh_frame_context = cpi->ext_refresh_frame_context;
200 cpi->ext_refresh_frame_context_pending = 0;
201 }
David Turner07dbd8e2019-01-08 17:16:25 +0000202 cm->allow_ref_frame_mvs = cpi->ext_use_ref_frame_mvs;
203
204 frame_params->error_resilient_mode = cpi->ext_use_error_resilient;
205 // A keyframe is already error resilient and keyframes with
206 // error_resilient_mode interferes with the use of show_existing_frame
207 // when forward reference keyframes are enabled.
David Turner475a3132019-01-18 15:17:17 +0000208 frame_params->error_resilient_mode &= frame_params->frame_type != KEY_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000209 // For bitstream conformance, s-frames must be error-resilient
David Turner475a3132019-01-18 15:17:17 +0000210 frame_params->error_resilient_mode |= frame_params->frame_type == S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000211}
212
213static int get_ref_frame_flags(const AV1_COMP *const cpi) {
Hui Su56f4ad42019-09-25 12:49:12 -0700214 static const MV_REFERENCE_FRAME
215 ref_frame_priority_order[INTER_REFS_PER_FRAME] = {
Hui Su75ce8ba2019-09-25 16:46:14 -0700216 LAST_FRAME, ALTREF_FRAME, BWDREF_FRAME, GOLDEN_FRAME,
217 ALTREF2_FRAME, LAST2_FRAME, LAST3_FRAME,
Hui Su56f4ad42019-09-25 12:49:12 -0700218 };
David Turner07dbd8e2019-01-08 17:16:25 +0000219 const AV1_COMMON *const cm = &cpi->common;
Hui Su56f4ad42019-09-25 12:49:12 -0700220 const RefCntBuffer *ref_frames[INTER_REFS_PER_FRAME];
221 for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
222 ref_frames[i] = get_ref_frame_buf(cm, ref_frame_priority_order[i]);
223 }
David Turner07dbd8e2019-01-08 17:16:25 +0000224
225 // cpi->ext_ref_frame_flags allows certain reference types to be disabled
226 // by the external interface. These are set by av1_apply_encoding_flags().
227 // Start with what the external interface allows, then suppress any reference
228 // types which we have found to be duplicates.
David Turner07dbd8e2019-01-08 17:16:25 +0000229 int flags = cpi->ext_ref_frame_flags;
230
Hui Su56f4ad42019-09-25 12:49:12 -0700231 for (int i = 1; i < INTER_REFS_PER_FRAME; ++i) {
232 const RefCntBuffer *const this_ref = ref_frames[i];
233 // If this_ref has appeared before, mark the corresponding ref frame as
Fyodor Kyslov915b9b82019-11-11 11:53:03 -0800234 // invalid. For nonrd mode, only disable GOLDEN_FRAME if it's the same
Marco Paniconi92580012019-12-10 11:05:04 -0800235 // as LAST_FRAME or ALTREF_FRAME (if ALTREF is being used in nonrd).
chiyotsai56681b52019-12-16 11:15:25 -0800236 int index = (cpi->sf.rt_sf.use_nonrd_pick_mode &&
Marco Paniconi45d2adf2019-09-29 19:49:18 -0700237 ref_frame_priority_order[i] == GOLDEN_FRAME)
chiyotsai56681b52019-12-16 11:15:25 -0800238 ? (1 + cpi->sf.rt_sf.use_nonrd_altref_frame)
Marco Paniconi45d2adf2019-09-29 19:49:18 -0700239 : i;
240 for (int j = 0; j < index; ++j) {
Hui Su56f4ad42019-09-25 12:49:12 -0700241 if (this_ref == ref_frames[j]) {
242 flags &= ~(1 << (ref_frame_priority_order[i] - 1));
243 break;
244 }
245 }
Fyodor Kyslov84abaea2019-06-25 14:44:14 -0700246 }
David Turner07dbd8e2019-01-08 17:16:25 +0000247 return flags;
248}
249
David Turnera7f133c2019-01-22 14:47:16 +0000250static int get_current_frame_ref_type(
251 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
David Turnera7f133c2019-01-22 14:47:16 +0000252 // We choose the reference "type" of this frame from the flags which indicate
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700253 // which reference frames will be refreshed by it. More than one of these
254 // flags may be set, so the order here implies an order of precedence. This is
255 // just used to choose the primary_ref_frame (as the most recent reference
256 // buffer of the same reference-type as the current frame)
David Turnera7f133c2019-01-22 14:47:16 +0000257
Jingning Han370d1162019-07-03 10:24:03 -0700258 (void)frame_params;
259 // TODO(jingning): This table should be a lot simpler with the new
260 // ARF system in place. Keep frame_params for the time being as we are
261 // still evaluating a few design options.
262 switch (cpi->gf_group.layer_depth[cpi->gf_group.index]) {
263 case 0: return 0;
264 case 1: return 1;
265 case MAX_ARF_LAYERS:
266 case MAX_ARF_LAYERS + 1: return 4;
267 default: return 7;
268 }
David Turnera7f133c2019-01-22 14:47:16 +0000269}
270
271static int choose_primary_ref_frame(
272 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
273 const AV1_COMMON *const cm = &cpi->common;
274
275 const int intra_only = frame_params->frame_type == KEY_FRAME ||
276 frame_params->frame_type == INTRA_ONLY_FRAME;
Marco Paniconi5b1e4732019-08-08 18:57:53 -0700277 if (intra_only || frame_params->error_resilient_mode || cpi->use_svc ||
David Turnera7f133c2019-01-22 14:47:16 +0000278 cpi->ext_use_primary_ref_none) {
279 return PRIMARY_REF_NONE;
280 }
281
282 // Find the most recent reference frame with the same reference type as the
283 // current frame
Jingning Han370d1162019-07-03 10:24:03 -0700284 FRAME_CONTEXT_INDEX current_ref_type =
David Turnera7f133c2019-01-22 14:47:16 +0000285 get_current_frame_ref_type(cpi, frame_params);
286 int wanted_fb = cpi->fb_of_context_type[current_ref_type];
287
288 int primary_ref_frame = PRIMARY_REF_NONE;
289 for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
290 if (get_ref_frame_map_idx(cm, ref_frame) == wanted_fb) {
291 primary_ref_frame = ref_frame - LAST_FRAME;
292 }
293 }
Jingning Han370d1162019-07-03 10:24:03 -0700294
David Turnera7f133c2019-01-22 14:47:16 +0000295 return primary_ref_frame;
296}
297
298static void update_fb_of_context_type(
299 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params,
300 int *const fb_of_context_type) {
301 const AV1_COMMON *const cm = &cpi->common;
Jingning Han370d1162019-07-03 10:24:03 -0700302 const int current_frame_ref_type =
303 get_current_frame_ref_type(cpi, frame_params);
David Turnera7f133c2019-01-22 14:47:16 +0000304
305 if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
306 cpi->ext_use_primary_ref_none) {
307 for (int i = 0; i < REF_FRAMES; i++) {
308 fb_of_context_type[i] = -1;
309 }
Jingning Han370d1162019-07-03 10:24:03 -0700310 fb_of_context_type[current_frame_ref_type] =
David Turnera7f133c2019-01-22 14:47:16 +0000311 cm->show_frame ? get_ref_frame_map_idx(cm, GOLDEN_FRAME)
312 : get_ref_frame_map_idx(cm, ALTREF_FRAME);
313 }
314
315 if (!encode_show_existing_frame(cm)) {
316 // Refresh fb_of_context_type[]: see encoder.h for explanation
David Turnera7f133c2019-01-22 14:47:16 +0000317 if (cm->current_frame.frame_type == KEY_FRAME) {
318 // All ref frames are refreshed, pick one that will live long enough
Jingning Han370d1162019-07-03 10:24:03 -0700319 fb_of_context_type[current_frame_ref_type] = 0;
David Turnera7f133c2019-01-22 14:47:16 +0000320 } else {
321 // If more than one frame is refreshed, it doesn't matter which one we
322 // pick so pick the first. LST sometimes doesn't refresh any: this is ok
Jingning Han370d1162019-07-03 10:24:03 -0700323
David Turnera7f133c2019-01-22 14:47:16 +0000324 for (int i = 0; i < REF_FRAMES; i++) {
325 if (cm->current_frame.refresh_frame_flags & (1 << i)) {
326 fb_of_context_type[current_frame_ref_type] = i;
327 break;
328 }
329 }
330 }
331 }
332}
333
David Turnere86ee0d2019-02-18 17:16:28 +0000334static int get_order_offset(const GF_GROUP *const gf_group,
David Turnerdedd8ff2019-01-23 13:59:46 +0000335 const EncodeFrameParams *const frame_params) {
David Turnera7f133c2019-01-22 14:47:16 +0000336 // shown frame by definition has order offset 0
337 // show_existing_frame ignores order_offset and simply takes the order_hint
338 // from the reference frame being shown.
David Turnere86ee0d2019-02-18 17:16:28 +0000339 if (frame_params->show_frame || frame_params->show_existing_frame) return 0;
David Turnera7f133c2019-01-22 14:47:16 +0000340
David Turnera7f133c2019-01-22 14:47:16 +0000341 const int arf_offset =
342 AOMMIN((MAX_GF_INTERVAL - 1), gf_group->arf_src_offset[gf_group->index]);
Urvang Joshi6ce7fbc2019-03-22 15:24:21 -0700343 return AOMMIN((MAX_GF_INTERVAL - 1), arf_offset);
David Turnera7f133c2019-01-22 14:47:16 +0000344}
345
David Turnerdedd8ff2019-01-23 13:59:46 +0000346static void adjust_frame_rate(AV1_COMP *cpi,
347 const struct lookahead_entry *source) {
348 int64_t this_duration;
349 int step = 0;
350
351 // Clear down mmx registers
352 aom_clear_system_state();
353
Marco Paniconi63971322019-08-15 21:32:05 -0700354 if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
355 cpi->framerate = cpi->svc.base_framerate;
356 av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
357 return;
358 }
359
David Turnerdedd8ff2019-01-23 13:59:46 +0000360 if (source->ts_start == cpi->first_time_stamp_ever) {
361 this_duration = source->ts_end - source->ts_start;
362 step = 1;
363 } else {
364 int64_t last_duration =
365 cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen;
366
367 this_duration = source->ts_end - cpi->last_end_time_stamp_seen;
368
369 // do a step update if the duration changes by 10%
370 if (last_duration)
371 step = (int)((this_duration - last_duration) * 10 / last_duration);
372 }
373
374 if (this_duration) {
375 if (step) {
376 av1_new_framerate(cpi, 10000000.0 / this_duration);
377 } else {
378 // Average this frame's rate into the last second's average
379 // frame rate. If we haven't seen 1 second yet, then average
380 // over the whole interval seen.
381 const double interval = AOMMIN(
382 (double)(source->ts_end - cpi->first_time_stamp_ever), 10000000.0);
383 double avg_duration = 10000000.0 / cpi->framerate;
384 avg_duration *= (interval - avg_duration + this_duration);
385 avg_duration /= interval;
386
387 av1_new_framerate(cpi, 10000000.0 / avg_duration);
388 }
389 }
390 cpi->last_time_stamp_seen = source->ts_start;
391 cpi->last_end_time_stamp_seen = source->ts_end;
392}
393
Urvang Joshif70375a2019-03-22 23:30:19 -0700394// If this is an alt-ref, returns the offset of the source frame used
395// as the arf midpoint. Otherwise, returns 0.
Jingning Hanf39a1ea2019-08-16 10:43:08 -0700396static int get_arf_src_index(GF_GROUP *gf_group, int pass) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000397 int arf_src_index = 0;
Jingning Hanf39a1ea2019-08-16 10:43:08 -0700398 if (pass != 1) arf_src_index = gf_group->arf_src_offset[gf_group->index];
Jingning Hanbb782982019-08-15 11:28:46 -0700399 return arf_src_index;
David Turnerdedd8ff2019-01-23 13:59:46 +0000400}
401
402// Called if this frame is an ARF or ARF2. Also handles forward-keyframes
403// For an ARF set arf2=0, for ARF2 set arf2=1
404// temporal_filtered is set to 1 if we temporally filter the ARF frame, so that
405// the correct post-filter buffer can be used.
Jingning Hanbb782982019-08-15 11:28:46 -0700406static struct lookahead_entry *setup_arf_frame(
407 AV1_COMP *const cpi, const int arf_src_index, int *code_arf,
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700408 EncodeFrameParams *const frame_params, int *show_existing_alt_ref) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000409 AV1_COMMON *const cm = &cpi->common;
410 RATE_CONTROL *const rc = &cpi->rc;
Jerome Jiang71647472019-05-30 12:01:57 -0700411#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +0000412 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Jerome Jiang71647472019-05-30 12:01:57 -0700413#endif
David Turnerdedd8ff2019-01-23 13:59:46 +0000414
415 assert(arf_src_index <= rc->frames_to_key);
Jingning Hanbb782982019-08-15 11:28:46 -0700416 *code_arf = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000417
418 struct lookahead_entry *source =
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530419 av1_lookahead_peek(cpi->lookahead, arf_src_index, cpi->compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000420
421 if (source != NULL) {
422 cm->showable_frame = 1;
423 cpi->alt_ref_source = source;
424
425 // When arf_src_index == rc->frames_to_key, it indicates a fwd_kf
Jingning Hanbb782982019-08-15 11:28:46 -0700426 if (arf_src_index == rc->frames_to_key) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000427 // Skip temporal filtering and mark as intra_only if we have a fwd_kf
David Turnerdedd8ff2019-01-23 13:59:46 +0000428 cpi->no_show_kf = 1;
429 } else {
Jerome Jiang71647472019-05-30 12:01:57 -0700430#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +0000431 if (oxcf->arnr_max_frames > 0) {
432 // Produce the filtered ARF frame.
Yunqing Wang1973f112019-10-18 15:50:04 -0700433 cm->current_frame.frame_type = INTER_FRAME;
434 FRAME_UPDATE_TYPE frame_update_type =
435 get_frame_update_type(&cpi->gf_group);
436 av1_configure_buffer_updates(cpi, frame_params, frame_update_type, 0);
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700437 *code_arf =
438 av1_temporal_filter(cpi, arf_src_index, show_existing_alt_ref);
Yunqing Wangb0d52fa2019-10-10 13:09:38 -0700439 if (*code_arf) {
440 aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
441 }
David Turnerdedd8ff2019-01-23 13:59:46 +0000442 }
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700443#else
444 (void)show_existing_alt_ref;
Jerome Jiang71647472019-05-30 12:01:57 -0700445#endif
David Turnerdedd8ff2019-01-23 13:59:46 +0000446 }
447 frame_params->show_frame = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000448 }
449 rc->source_alt_ref_pending = 0;
450 return source;
451}
452
453// Determine whether there is a forced keyframe pending in the lookahead buffer
454static int is_forced_keyframe_pending(struct lookahead_ctx *lookahead,
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530455 const int up_to_index,
456 const COMPRESSOR_STAGE compressor_stage) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000457 for (int i = 0; i <= up_to_index; i++) {
Mufaddal Chakera73b7b702019-12-09 11:44:55 +0530458 const struct lookahead_entry *e =
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530459 av1_lookahead_peek(lookahead, i, compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000460 if (e == NULL) {
461 // We have reached the end of the lookahead buffer and not early-returned
462 // so there isn't a forced key-frame pending.
463 return 0;
464 } else if (e->flags == AOM_EFLAG_FORCE_KF) {
465 return 1;
466 } else {
467 continue;
468 }
469 }
470 return 0; // Never reached
471}
472
Urvang Joshif70375a2019-03-22 23:30:19 -0700473// Check if we should encode an ARF or internal ARF. If not, try a LAST
David Turnerdedd8ff2019-01-23 13:59:46 +0000474// Do some setup associated with the chosen source
David Turner4f1f1812019-01-24 17:00:24 +0000475// temporal_filtered, flush, and frame_update_type are outputs.
David Turnerdedd8ff2019-01-23 13:59:46 +0000476// Return the frame source, or NULL if we couldn't find one
Yaowu Xufac3d862019-04-26 15:43:03 -0700477static struct lookahead_entry *choose_frame_source(
Jingning Hanbb782982019-08-15 11:28:46 -0700478 AV1_COMP *const cpi, int *const code_arf, int *const flush,
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700479 struct lookahead_entry **last_source, EncodeFrameParams *const frame_params,
480 int *show_existing_alt_ref) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000481 AV1_COMMON *const cm = &cpi->common;
482 struct lookahead_entry *source = NULL;
Jingning Hanbb782982019-08-15 11:28:46 -0700483 *code_arf = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000484
485 // Should we encode an alt-ref frame.
Jingning Hanf39a1ea2019-08-16 10:43:08 -0700486 int arf_src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530487 if (arf_src_index && is_forced_keyframe_pending(cpi->lookahead, arf_src_index,
488 cpi->compressor_stage)) {
David Turnerdedd8ff2019-01-23 13:59:46 +0000489 arf_src_index = 0;
490 *flush = 1;
491 }
492
Jingning Hanbb782982019-08-15 11:28:46 -0700493 if (arf_src_index)
Yunqing Wang699fa7f2019-10-15 17:40:46 -0700494 source = setup_arf_frame(cpi, arf_src_index, code_arf, frame_params,
495 show_existing_alt_ref);
David Turnerdedd8ff2019-01-23 13:59:46 +0000496
David Turnerdedd8ff2019-01-23 13:59:46 +0000497 if (!source) {
498 // Get last frame source.
499 if (cm->current_frame.frame_number > 0) {
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530500 *last_source =
501 av1_lookahead_peek(cpi->lookahead, -1, cpi->compressor_stage);
David Turnerdedd8ff2019-01-23 13:59:46 +0000502 }
503 // Read in the source frame.
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530504 source = av1_lookahead_pop(cpi->lookahead, *flush, cpi->compressor_stage);
David Turner4f1f1812019-01-24 17:00:24 +0000505 if (source == NULL) return NULL;
David Turner4f1f1812019-01-24 17:00:24 +0000506 frame_params->show_frame = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +0000507
David Turner4f1f1812019-01-24 17:00:24 +0000508 // Check to see if the frame should be encoded as an arf overlay.
Jingning Hanbb782982019-08-15 11:28:46 -0700509 if (cpi->alt_ref_source == source) cpi->alt_ref_source = NULL;
David Turnerdedd8ff2019-01-23 13:59:46 +0000510 }
511 return source;
512}
513
David Turnerb0c0aa32019-01-28 16:17:13 +0000514// Don't allow a show_existing_frame to coincide with an error resilient or
515// S-Frame. An exception can be made in the case of a keyframe, since it does
516// not depend on any previous frames.
David Turner73245762019-02-11 16:42:34 +0000517static int allow_show_existing(const AV1_COMP *const cpi,
518 unsigned int frame_flags) {
David Turnerb0c0aa32019-01-28 16:17:13 +0000519 if (cpi->common.current_frame.frame_number == 0) return 0;
520
521 const struct lookahead_entry *lookahead_src =
Mufaddal Chakeraac828682019-12-13 16:31:42 +0530522 av1_lookahead_peek(cpi->lookahead, 0, cpi->compressor_stage);
David Turnerb0c0aa32019-01-28 16:17:13 +0000523 if (lookahead_src == NULL) return 1;
524
525 const int is_error_resilient =
526 cpi->oxcf.error_resilient_mode ||
527 (lookahead_src->flags & AOM_EFLAG_ERROR_RESILIENT);
528 const int is_s_frame =
529 cpi->oxcf.s_frame_mode || (lookahead_src->flags & AOM_EFLAG_SET_S_FRAME);
530 const int is_key_frame =
David Turner73245762019-02-11 16:42:34 +0000531 (cpi->rc.frames_to_key == 0) || (frame_flags & FRAMEFLAGS_KEY);
David Turnerb0c0aa32019-01-28 16:17:13 +0000532 return !(is_error_resilient || is_s_frame) || is_key_frame;
533}
534
David Turner73245762019-02-11 16:42:34 +0000535// Update frame_flags to tell the encoder's caller what sort of frame was
536// encoded.
537static void update_frame_flags(AV1_COMP *cpi, unsigned int *frame_flags) {
538 if (encode_show_existing_frame(&cpi->common)) {
539 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
540 *frame_flags &= ~FRAMEFLAGS_BWDREF;
541 *frame_flags &= ~FRAMEFLAGS_ALTREF;
542 *frame_flags &= ~FRAMEFLAGS_KEY;
543 return;
544 }
545
546 if (cpi->refresh_golden_frame == 1) {
547 *frame_flags |= FRAMEFLAGS_GOLDEN;
548 } else {
549 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
550 }
551
552 if (cpi->refresh_alt_ref_frame == 1) {
553 *frame_flags |= FRAMEFLAGS_ALTREF;
554 } else {
555 *frame_flags &= ~FRAMEFLAGS_ALTREF;
556 }
557
558 if (cpi->refresh_bwd_ref_frame == 1) {
559 *frame_flags |= FRAMEFLAGS_BWDREF;
560 } else {
561 *frame_flags &= ~FRAMEFLAGS_BWDREF;
562 }
563
564 if (cpi->common.current_frame.frame_type == KEY_FRAME) {
565 *frame_flags |= FRAMEFLAGS_KEY;
566 } else {
567 *frame_flags &= ~FRAMEFLAGS_KEY;
568 }
569}
570
571#define DUMP_REF_FRAME_IMAGES 0
572
573#if DUMP_REF_FRAME_IMAGES == 1
574static int dump_one_image(AV1_COMMON *cm,
575 const YV12_BUFFER_CONFIG *const ref_buf,
576 char *file_name) {
577 int h;
578 FILE *f_ref = NULL;
579
580 if (ref_buf == NULL) {
581 printf("Frame data buffer is NULL.\n");
582 return AOM_CODEC_MEM_ERROR;
583 }
584
585 if ((f_ref = fopen(file_name, "wb")) == NULL) {
586 printf("Unable to open file %s to write.\n", file_name);
587 return AOM_CODEC_MEM_ERROR;
588 }
589
590 // --- Y ---
591 for (h = 0; h < cm->height; ++h) {
592 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
593 }
594 // --- U ---
595 for (h = 0; h < (cm->height >> 1); ++h) {
596 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
597 f_ref);
598 }
599 // --- V ---
600 for (h = 0; h < (cm->height >> 1); ++h) {
601 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
602 f_ref);
603 }
604
605 fclose(f_ref);
606
607 return AOM_CODEC_OK;
608}
609
610static void dump_ref_frame_images(AV1_COMP *cpi) {
611 AV1_COMMON *const cm = &cpi->common;
612 MV_REFERENCE_FRAME ref_frame;
613
614 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
615 char file_name[256] = "";
616 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
617 cm->current_frame.frame_number, ref_frame);
618 dump_one_image(cm, get_ref_frame_yv12_buf(cpi, ref_frame), file_name);
619 }
620}
621#endif // DUMP_REF_FRAME_IMAGES == 1
622
Jingning Han81d6fbb2019-07-15 10:14:13 -0700623int av1_get_refresh_ref_frame_map(int refresh_frame_flags) {
Jingning Hanf58175c2019-07-07 15:02:00 -0700624 int ref_map_index = INVALID_IDX;
625
626 for (ref_map_index = 0; ref_map_index < REF_FRAMES; ++ref_map_index)
627 if ((refresh_frame_flags >> ref_map_index) & 1) break;
628
629 return ref_map_index;
630}
631
Jingning Han4711eb12019-08-01 09:56:59 -0700632static void update_arf_stack(int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700633 RefBufferStack *ref_buffer_stack) {
Jingning Han42266ca2019-07-12 14:37:16 -0700634 if (ref_buffer_stack->arf_stack_size >= 0) {
635 if (ref_buffer_stack->arf_stack[0] == ref_map_index)
636 stack_pop(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size);
Jingning Hanf58175c2019-07-07 15:02:00 -0700637 }
638
Jingning Han42266ca2019-07-12 14:37:16 -0700639 if (ref_buffer_stack->lst_stack_size) {
640 for (int i = ref_buffer_stack->lst_stack_size - 1; i >= 0; --i) {
641 if (ref_buffer_stack->lst_stack[i] == ref_map_index) {
642 for (int idx = i; idx < ref_buffer_stack->lst_stack_size - 1; ++idx)
643 ref_buffer_stack->lst_stack[idx] =
644 ref_buffer_stack->lst_stack[idx + 1];
Cheng Chenc86d2bf2019-09-05 15:07:47 -0700645 ref_buffer_stack->lst_stack[ref_buffer_stack->lst_stack_size - 1] =
646 INVALID_IDX;
Jingning Han42266ca2019-07-12 14:37:16 -0700647 --ref_buffer_stack->lst_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700648 }
649 }
650 }
651
Jingning Han42266ca2019-07-12 14:37:16 -0700652 if (ref_buffer_stack->gld_stack_size) {
653 for (int i = ref_buffer_stack->gld_stack_size - 1; i >= 0; --i) {
654 if (ref_buffer_stack->gld_stack[i] == ref_map_index) {
655 for (int idx = i; idx < ref_buffer_stack->gld_stack_size - 1; ++idx)
656 ref_buffer_stack->gld_stack[idx] =
657 ref_buffer_stack->gld_stack[idx + 1];
Cheng Chenc86d2bf2019-09-05 15:07:47 -0700658 ref_buffer_stack->gld_stack[ref_buffer_stack->gld_stack_size - 1] =
659 INVALID_IDX;
Jingning Han42266ca2019-07-12 14:37:16 -0700660 --ref_buffer_stack->gld_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700661 }
662 }
663 }
664}
665
Jingning Han647f2d12019-07-23 14:15:42 -0700666// Update reference frame stack info.
Jingning Han42266ca2019-07-12 14:37:16 -0700667void av1_update_ref_frame_map(AV1_COMP *cpi,
668 FRAME_UPDATE_TYPE frame_update_type,
Sarah Parkeredffc652019-10-25 16:30:32 -0700669 int show_existing_frame, int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700670 RefBufferStack *ref_buffer_stack) {
David Turner73245762019-02-11 16:42:34 +0000671 AV1_COMMON *const cm = &cpi->common;
Jingning Han47aaf872019-07-21 14:56:32 -0700672 // TODO(jingning): Consider the S-frame same as key frame for the
673 // reference frame tracking purpose. The logic might be better
674 // expressed than converting the frame update type.
675 if (frame_is_sframe(cm)) frame_update_type = KEY_FRAME;
676
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700677 if (is_frame_droppable(cpi)) return;
678
Jingning Han81d6fbb2019-07-15 10:14:13 -0700679 switch (frame_update_type) {
680 case KEY_FRAME:
Sarah Parkeredffc652019-10-25 16:30:32 -0700681 if (show_existing_frame)
682 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
683 &ref_buffer_stack->arf_stack_size);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700684 stack_reset(ref_buffer_stack->lst_stack,
685 &ref_buffer_stack->lst_stack_size);
686 stack_reset(ref_buffer_stack->gld_stack,
687 &ref_buffer_stack->gld_stack_size);
688 stack_reset(ref_buffer_stack->arf_stack,
689 &ref_buffer_stack->arf_stack_size);
690 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
691 ref_map_index);
692 break;
693 case GF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700694 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700695 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
696 ref_map_index);
Fyodor Kyslov915b9b82019-11-11 11:53:03 -0800697 // For nonrd_mode: update LAST as well on GF_UPDATE frame.
chiyotsai56681b52019-12-16 11:15:25 -0800698 if (cpi->sf.rt_sf.use_nonrd_pick_mode)
Marco Paniconifa29e162019-08-05 18:08:04 -0700699 stack_push(ref_buffer_stack->lst_stack,
700 &ref_buffer_stack->lst_stack_size, ref_map_index);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700701 break;
702 case LF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700703 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700704 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
705 ref_map_index);
706 break;
707 case ARF_UPDATE:
708 case INTNL_ARF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700709 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700710 stack_push(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size,
711 ref_map_index);
712 break;
713 case OVERLAY_UPDATE:
Jingning Han5738e032019-07-22 15:22:52 -0700714 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
715 &ref_buffer_stack->arf_stack_size);
716 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
717 ref_map_index);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700718 break;
719 case INTNL_OVERLAY_UPDATE:
720 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
721 &ref_buffer_stack->arf_stack_size);
722 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
723 ref_map_index);
724 break;
725 default: assert(0 && "unknown type");
Jingning Hancf6d3252019-07-03 14:26:45 -0700726 }
Jingning Han84a70502019-07-19 11:38:14 -0700727 return;
David Turner73245762019-02-11 16:42:34 +0000728}
729
Jingning Han42266ca2019-07-12 14:37:16 -0700730static int get_free_ref_map_index(const RefBufferStack *ref_buffer_stack) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700731 for (int idx = 0; idx < REF_FRAMES; ++idx) {
732 int is_free = 1;
Jingning Han42266ca2019-07-12 14:37:16 -0700733 for (int i = 0; i < ref_buffer_stack->arf_stack_size; ++i) {
734 if (ref_buffer_stack->arf_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700735 is_free = 0;
736 break;
737 }
738 }
739
Jingning Han42266ca2019-07-12 14:37:16 -0700740 for (int i = 0; i < ref_buffer_stack->lst_stack_size; ++i) {
741 if (ref_buffer_stack->lst_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700742 is_free = 0;
743 break;
744 }
745 }
746
Jingning Han42266ca2019-07-12 14:37:16 -0700747 for (int i = 0; i < ref_buffer_stack->gld_stack_size; ++i) {
748 if (ref_buffer_stack->gld_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700749 is_free = 0;
750 break;
751 }
752 }
753
754 if (is_free) return idx;
755 }
756 return INVALID_IDX;
757}
758
Jingning Han42266ca2019-07-12 14:37:16 -0700759int av1_get_refresh_frame_flags(const AV1_COMP *const cpi,
760 const EncodeFrameParams *const frame_params,
761 FRAME_UPDATE_TYPE frame_update_type,
762 const RefBufferStack *const ref_buffer_stack) {
David Turner6e8b4d92019-02-18 15:01:33 +0000763 const AV1_COMMON *const cm = &cpi->common;
764
765 // Switch frames and shown key-frames overwrite all reference slots
766 if ((frame_params->frame_type == KEY_FRAME && frame_params->show_frame) ||
767 frame_params->frame_type == S_FRAME)
768 return 0xFF;
769
770 // show_existing_frames don't actually send refresh_frame_flags so set the
771 // flags to 0 to keep things consistent.
David Turnere86ee0d2019-02-18 17:16:28 +0000772 if (frame_params->show_existing_frame &&
773 (!frame_params->error_resilient_mode ||
774 frame_params->frame_type == KEY_FRAME)) {
David Turner6e8b4d92019-02-18 15:01:33 +0000775 return 0;
776 }
777
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700778 if (is_frame_droppable(cpi)) return 0;
779
David Turner6e8b4d92019-02-18 15:01:33 +0000780 int refresh_mask = 0;
781
David Turner6e8b4d92019-02-18 15:01:33 +0000782 if (cpi->ext_refresh_frame_flags_pending) {
Marco Paniconid8574e32019-08-04 21:30:12 -0700783 if (cpi->svc.external_ref_frame_config) {
784 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
785 int ref_frame_map_idx = cpi->svc.ref_idx[i];
Marco Paniconie92d7732019-08-20 09:40:37 -0700786 refresh_mask |= cpi->svc.refresh[ref_frame_map_idx]
787 << ref_frame_map_idx;
Marco Paniconid8574e32019-08-04 21:30:12 -0700788 }
789 return refresh_mask;
790 }
David Turner6e8b4d92019-02-18 15:01:33 +0000791 // Unfortunately the encoder interface reflects the old refresh_*_frame
792 // flags so we have to replicate the old refresh_frame_flags logic here in
793 // order to preserve the behaviour of the flag overrides.
Marco Paniconi314bc362019-08-13 10:53:02 -0700794 int ref_frame_map_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
Jingning Han0a2af4e2019-07-08 19:30:03 -0700795 if (ref_frame_map_idx != INVALID_IDX)
796 refresh_mask |= cpi->ext_refresh_last_frame << ref_frame_map_idx;
797
798 ref_frame_map_idx = get_ref_frame_map_idx(cm, EXTREF_FRAME);
799 if (ref_frame_map_idx != INVALID_IDX)
800 refresh_mask |= cpi->ext_refresh_bwd_ref_frame << ref_frame_map_idx;
801
802 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF2_FRAME);
803 if (ref_frame_map_idx != INVALID_IDX)
804 refresh_mask |= cpi->ext_refresh_alt2_ref_frame << ref_frame_map_idx;
805
David Turner6e8b4d92019-02-18 15:01:33 +0000806 if (frame_update_type == OVERLAY_UPDATE) {
Jingning Han5738e032019-07-22 15:22:52 -0700807 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
808 if (ref_frame_map_idx != INVALID_IDX)
809 refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000810 } else {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700811 ref_frame_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
812 if (ref_frame_map_idx != INVALID_IDX)
813 refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
814
815 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
816 if (ref_frame_map_idx != INVALID_IDX)
817 refresh_mask |= cpi->ext_refresh_alt_ref_frame << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000818 }
819 return refresh_mask;
820 }
821
Jingning Hanc9c172d2019-07-23 14:10:32 -0700822 // Search for the open slot to store the current frame.
Jingning Han81d6fbb2019-07-15 10:14:13 -0700823 int free_fb_index = get_free_ref_map_index(ref_buffer_stack);
Jingning Han0a2af4e2019-07-08 19:30:03 -0700824 switch (frame_update_type) {
825 case KF_UPDATE:
826 case GF_UPDATE:
827 if (free_fb_index != INVALID_IDX) {
828 refresh_mask = 1 << free_fb_index;
829 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700830 if (ref_buffer_stack->gld_stack_size)
831 refresh_mask =
832 1 << ref_buffer_stack
833 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700834 else
Jingning Han42266ca2019-07-12 14:37:16 -0700835 refresh_mask =
836 1 << ref_buffer_stack
837 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700838 }
839 break;
840 case LF_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 if (ref_buffer_stack->lst_stack_size >= 2)
845 refresh_mask =
846 1 << ref_buffer_stack
847 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700848 else
849 assert(0 && "No ref map index found");
850 }
851 break;
852 case ARF_UPDATE:
853 if (free_fb_index != INVALID_IDX) {
854 refresh_mask = 1 << free_fb_index;
855 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700856 if (ref_buffer_stack->gld_stack_size >= 3)
857 refresh_mask =
858 1 << ref_buffer_stack
859 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
860 else if (ref_buffer_stack->lst_stack_size >= 2)
861 refresh_mask =
862 1 << ref_buffer_stack
863 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700864 else
865 assert(0 && "No ref map index found");
866 }
867 break;
868 case INTNL_ARF_UPDATE:
869 if (free_fb_index != INVALID_IDX) {
870 refresh_mask = 1 << free_fb_index;
871 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700872 refresh_mask =
873 1 << ref_buffer_stack
874 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700875 }
876 break;
Jingning Han5738e032019-07-22 15:22:52 -0700877 case OVERLAY_UPDATE: break;
Jingning Han0a2af4e2019-07-08 19:30:03 -0700878 case INTNL_OVERLAY_UPDATE: break;
879 default: assert(0); break;
880 }
881
882 return refresh_mask;
David Turner6e8b4d92019-02-18 15:01:33 +0000883}
884
Cheng Chen7abe3132019-06-19 11:55:28 -0700885#if !CONFIG_REALTIME_ONLY
Cheng Chen5083a9f2019-07-12 15:33:34 -0700886void setup_mi(AV1_COMP *const cpi, YV12_BUFFER_CONFIG *src) {
887 AV1_COMMON *const cm = &cpi->common;
888 const int num_planes = av1_num_planes(cm);
889 MACROBLOCK *const x = &cpi->td.mb;
890 MACROBLOCKD *const xd = &x->e_mbd;
891
892 av1_setup_src_planes(x, src, 0, 0, num_planes, cm->seq_params.sb_size);
893
894 av1_setup_block_planes(xd, cm->seq_params.subsampling_x,
895 cm->seq_params.subsampling_y, num_planes);
896
897 xd->mi = cm->mi_grid_base;
898 xd->mi[0] = cm->mi;
Hui Su52b7ddc2019-10-10 16:27:16 -0700899 xd->tx_type_map = cm->tx_type_map;
900 xd->tx_type_map_stride = cm->mi_stride;
Cheng Chen5083a9f2019-07-12 15:33:34 -0700901}
902
Cheng Chen7abe3132019-06-19 11:55:28 -0700903// Apply temporal filtering to key frames and encode the filtered frame.
904// If the current frame is not key frame, this function is identical to
905// av1_encode().
906static int denoise_and_encode(AV1_COMP *const cpi, uint8_t *const dest,
907 EncodeFrameInput *const frame_input,
908 EncodeFrameParams *const frame_params,
909 EncodeFrameResults *const frame_results,
910 int *temporal_filtered) {
Cheng Chen0fcf6f82019-10-11 11:41:19 -0700911 if (frame_params->frame_type != KEY_FRAME ||
912 !cpi->oxcf.enable_keyframe_filtering) {
Cheng Chen7abe3132019-06-19 11:55:28 -0700913 if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
914 AOM_CODEC_OK) {
915 return AOM_CODEC_ERROR;
916 }
917 return AOM_CODEC_OK;
918 }
919
920 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
921 AV1_COMMON *const cm = &cpi->common;
922 double noise_level;
923 const int use_hbd = frame_input->source->flags & YV12_FLAG_HIGHBITDEPTH;
Jingning Han97b64a72019-10-08 11:40:51 -0700924 const int num_planes = av1_num_planes(cm);
925
Cheng Chen7abe3132019-06-19 11:55:28 -0700926 if (use_hbd) {
927 noise_level = highbd_estimate_noise(
928 frame_input->source->y_buffer, frame_input->source->y_crop_width,
929 frame_input->source->y_crop_height, frame_input->source->y_stride,
930 cm->seq_params.bit_depth, EDGE_THRESHOLD);
931 } else {
932 noise_level = estimate_noise(frame_input->source->y_buffer,
933 frame_input->source->y_crop_width,
934 frame_input->source->y_crop_height,
935 frame_input->source->y_stride, EDGE_THRESHOLD);
936 }
937 const int apply_filtering =
Mufaddal Chakera4eba2622019-12-11 14:06:56 +0530938 !is_stat_generation_stage(cpi) && frame_params->frame_type == KEY_FRAME &&
Sarah Parker21f1e6e2019-11-15 16:48:29 -0800939 !frame_params->show_existing_frame &&
Cheng Chen7abe3132019-06-19 11:55:28 -0700940 cpi->rc.frames_to_key > NUM_KEY_FRAME_DENOISING && noise_level > 0 &&
941 !is_lossless_requested(oxcf) && oxcf->arnr_max_frames > 0;
Yunqing Wangce71fd72019-10-18 17:23:58 -0700942 // Save the pointer to the original source image.
943 YV12_BUFFER_CONFIG *source_kf_buffer = frame_input->source;
Cheng Chen7abe3132019-06-19 11:55:28 -0700944
945 // Apply filtering to key frame and encode.
946 if (apply_filtering) {
Cheng Chen5083a9f2019-07-12 15:33:34 -0700947 // Initialization for frame motion estimation.
948 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
949 av1_init_context_buffers(cm);
950 setup_mi(cpi, frame_input->source);
951 av1_init_macroblockd(cm, xd, NULL);
chiyotsaia7091f12019-08-09 16:48:27 -0700952 const int ext_mi_size = cm->mi_alloc_rows * cm->mi_alloc_cols;
Remya0cce44c2019-08-16 11:57:24 +0530953 memset(cpi->mbmi_ext_frame_base, 0,
954 ext_mi_size * sizeof(*cpi->mbmi_ext_frame_base));
Cheng Chen5083a9f2019-07-12 15:33:34 -0700955
956 av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
957 av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
958 av1_set_rd_speed_thresholds(cpi);
959 av1_setup_frame_buf_refs(cm);
960 av1_setup_frame_sign_bias(cm);
961 av1_frame_init_quantizer(cpi);
962 av1_setup_past_independence(cm);
963
Sarah Parker21f1e6e2019-11-15 16:48:29 -0800964 if (!frame_params->show_frame) {
965 int arf_src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
966 av1_temporal_filter(cpi, -1 * arf_src_index, NULL);
967 } else {
968 av1_temporal_filter(cpi, -1, NULL);
969 }
Cheng Chen7abe3132019-06-19 11:55:28 -0700970 aom_extend_frame_borders(&cpi->alt_ref_buffer, num_planes);
Cheng Chen5083a9f2019-07-12 15:33:34 -0700971 // Use the filtered frame for encoding.
Cheng Chen7abe3132019-06-19 11:55:28 -0700972 frame_input->source = &cpi->alt_ref_buffer;
Akshata Jadhavc2098842019-11-26 16:16:29 +0530973 // Copy metadata info to alt-ref buffer.
974 aom_remove_metadata_from_frame_buffer(frame_input->source);
975 aom_copy_metadata_to_frame_buffer(frame_input->source,
976 source_kf_buffer->metadata);
Cheng Chen5083a9f2019-07-12 15:33:34 -0700977 *temporal_filtered = 1;
Cheng Chen7abe3132019-06-19 11:55:28 -0700978 }
Jingning Han97b64a72019-10-08 11:40:51 -0700979
Mufaddal Chakerae7326122019-12-04 14:49:09 +0530980 if (oxcf->lag_in_frames > 0 && !is_stat_generation_stage(cpi) &&
Jingning Han97b64a72019-10-08 11:40:51 -0700981 frame_params->frame_type == KEY_FRAME && frame_params->show_frame) {
982 av1_configure_buffer_updates(cpi, frame_params, KEY_FRAME, 0);
983 av1_set_frame_size(cpi, cm->width, cm->height);
984 av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
Cheng Chen3fb3f862019-11-26 14:26:24 -0800985 if (cpi->oxcf.enable_tpl_model) {
986 av1_tpl_setup_stats(cpi, frame_params, frame_input);
987 }
Jingning Han97b64a72019-10-08 11:40:51 -0700988 }
989
990 if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
991 AOM_CODEC_OK) {
992 return AOM_CODEC_ERROR;
993 }
994
995 // Set frame_input source to true source for psnr calculation.
996 if (oxcf->arnr_max_frames > 0 && *temporal_filtered) {
Yunqing Wangce71fd72019-10-18 17:23:58 -0700997 cpi->source = source_kf_buffer;
998 cpi->unscaled_source = source_kf_buffer;
Jingning Han97b64a72019-10-08 11:40:51 -0700999 }
1000
Cheng Chen7abe3132019-06-19 11:55:28 -07001001 return AOM_CODEC_OK;
1002}
1003#endif // !CONFIG_REALTIME_ONLY
1004
Jingning Handae645a2019-08-01 10:00:11 -07001005void av1_get_ref_frames(AV1_COMP *const cpi, RefBufferStack *ref_buffer_stack) {
Jingning Han0a2af4e2019-07-08 19:30:03 -07001006 AV1_COMMON *cm = &cpi->common;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001007
Jingning Han42266ca2019-07-12 14:37:16 -07001008 const int arf_stack_size = ref_buffer_stack->arf_stack_size;
1009 const int lst_stack_size = ref_buffer_stack->lst_stack_size;
1010 const int gld_stack_size = ref_buffer_stack->gld_stack_size;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001011
1012 // Initialization
1013 for (int i = 0; i < REF_FRAMES; ++i) cm->remapped_ref_idx[i] = INVALID_IDX;
1014
1015 if (arf_stack_size) {
1016 cm->remapped_ref_idx[ALTREF_FRAME - LAST_FRAME] =
Jingning Han42266ca2019-07-12 14:37:16 -07001017 ref_buffer_stack->arf_stack[arf_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001018
1019 if (arf_stack_size > 1)
Jingning Han42266ca2019-07-12 14:37:16 -07001020 cm->remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] =
1021 ref_buffer_stack->arf_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001022
1023 if (arf_stack_size > 2)
Jingning Han42266ca2019-07-12 14:37:16 -07001024 cm->remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] =
1025 ref_buffer_stack->arf_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001026 }
1027
1028 if (lst_stack_size) {
Jingning Han42266ca2019-07-12 14:37:16 -07001029 cm->remapped_ref_idx[LAST_FRAME - LAST_FRAME] =
1030 ref_buffer_stack->lst_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001031
1032 if (lst_stack_size > 1)
Jingning Han42266ca2019-07-12 14:37:16 -07001033 cm->remapped_ref_idx[LAST2_FRAME - LAST_FRAME] =
1034 ref_buffer_stack->lst_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001035 }
1036
1037 if (gld_stack_size) {
1038 cm->remapped_ref_idx[GOLDEN_FRAME - LAST_FRAME] =
Jingning Hanba8052c2019-07-23 13:34:43 -07001039 ref_buffer_stack->gld_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001040
1041 if (gld_stack_size > 1) {
1042 if (arf_stack_size <= 1)
Jingning Han42266ca2019-07-12 14:37:16 -07001043 cm->remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] =
Jingning Hanba8052c2019-07-23 13:34:43 -07001044 ref_buffer_stack->gld_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001045 else
Jingning Han42266ca2019-07-12 14:37:16 -07001046 cm->remapped_ref_idx[LAST3_FRAME - LAST_FRAME] =
Jingning Hanba8052c2019-07-23 13:34:43 -07001047 ref_buffer_stack->gld_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001048 }
1049 }
1050
1051 for (int idx = ALTREF_FRAME - LAST_FRAME; idx >= 0; --idx) {
1052 int ref_map_index = cm->remapped_ref_idx[idx];
1053
1054 if (ref_map_index != INVALID_IDX) continue;
1055
Jingning Han42266ca2019-07-12 14:37:16 -07001056 for (int i = 0;
1057 i < ref_buffer_stack->arf_stack_size && ref_map_index == INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001058 ++i) {
1059 int ref_idx = 0;
1060 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx)
Jingning Han42266ca2019-07-12 14:37:16 -07001061 if (ref_buffer_stack->arf_stack[i] == cm->remapped_ref_idx[ref_idx])
1062 break;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001063
1064 // not in use
1065 if (ref_idx > ALTREF_FRAME - LAST_FRAME) {
Jingning Han42266ca2019-07-12 14:37:16 -07001066 ref_map_index = ref_buffer_stack->arf_stack[i];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001067 break;
1068 }
1069 }
1070
Jingning Han42266ca2019-07-12 14:37:16 -07001071 for (int i = 0;
1072 i < ref_buffer_stack->gld_stack_size && ref_map_index == INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001073 ++i) {
1074 int ref_idx = 0;
1075 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx)
Jingning Han42266ca2019-07-12 14:37:16 -07001076 if (ref_buffer_stack->gld_stack[i] == cm->remapped_ref_idx[ref_idx])
1077 break;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001078
1079 // not in use
1080 if (ref_idx > ALTREF_FRAME - LAST_FRAME) {
Jingning Han42266ca2019-07-12 14:37:16 -07001081 ref_map_index = ref_buffer_stack->gld_stack[i];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001082 break;
1083 }
1084 }
1085
Jingning Han42266ca2019-07-12 14:37:16 -07001086 for (int i = 0;
1087 i < ref_buffer_stack->lst_stack_size && ref_map_index == INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001088 ++i) {
1089 int ref_idx = 0;
1090 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx)
Jingning Han42266ca2019-07-12 14:37:16 -07001091 if (ref_buffer_stack->lst_stack[i] == cm->remapped_ref_idx[ref_idx])
1092 break;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001093
1094 // not in use
1095 if (ref_idx > ALTREF_FRAME - LAST_FRAME) {
Jingning Han42266ca2019-07-12 14:37:16 -07001096 ref_map_index = ref_buffer_stack->lst_stack[i];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001097 break;
1098 }
1099 }
1100
1101 if (ref_map_index != INVALID_IDX)
1102 cm->remapped_ref_idx[idx] = ref_map_index;
1103 else
Jingning Han42266ca2019-07-12 14:37:16 -07001104 cm->remapped_ref_idx[idx] = ref_buffer_stack->gld_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001105 }
Jingning Han42266ca2019-07-12 14:37:16 -07001106
1107 return;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001108}
1109
David Turner056f7cd2019-01-07 17:48:13 +00001110int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
David Turner1539bb02019-01-24 15:28:13 +00001111 uint8_t *const dest, unsigned int *frame_flags,
David Turnerdedd8ff2019-01-23 13:59:46 +00001112 int64_t *const time_stamp, int64_t *const time_end,
Yue Chen1bc5be62018-08-24 13:57:32 -07001113 const aom_rational64_t *const timestamp_ratio,
1114 int flush) {
David Turner1539bb02019-01-24 15:28:13 +00001115 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
David Turner475a3132019-01-18 15:17:17 +00001116 AV1_COMMON *const cm = &cpi->common;
Jingning Hana7293932019-08-15 15:46:49 -07001117 GF_GROUP *gf_group = &cpi->gf_group;
David Turner056f7cd2019-01-07 17:48:13 +00001118
David Turnerdedd8ff2019-01-23 13:59:46 +00001119 EncodeFrameInput frame_input;
David Turner04b70d82019-01-24 15:39:19 +00001120 EncodeFrameParams frame_params;
1121 EncodeFrameResults frame_results;
David Turnerdedd8ff2019-01-23 13:59:46 +00001122 memset(&frame_input, 0, sizeof(frame_input));
David Turner04b70d82019-01-24 15:39:19 +00001123 memset(&frame_params, 0, sizeof(frame_params));
1124 memset(&frame_results, 0, sizeof(frame_results));
1125
Sarah Parker97803fc2019-05-17 14:15:37 -07001126 // TODO(sarahparker) finish bit allocation for one pass pyramid
Mufaddal Chakera3bcc72c2019-12-11 14:38:37 +05301127 if (has_no_stats_stage(cpi) && oxcf->rc_mode != AOM_Q)
Sarah Parker97803fc2019-05-17 14:15:37 -07001128 cpi->oxcf.gf_max_pyr_height = USE_ALTREF_FOR_ONE_PASS;
1129
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301130 if (!is_stat_generation_stage(cpi)) {
Sarah Parker2beb1d12019-10-25 16:30:32 -07001131 // If this is a forward keyframe, mark as a show_existing_frame
1132 if (cpi->oxcf.fwd_kf_enabled && (gf_group->index == gf_group->size) &&
1133 gf_group->update_type[1] == ARF_UPDATE && cpi->rc.frames_to_key == 0) {
1134 frame_params.show_existing_frame = 1;
1135 } else {
1136 frame_params.show_existing_frame =
1137 ((oxcf->enable_overlay == 0 || cpi->sf.disable_overlay_frames ||
1138 cpi->show_existing_alt_ref) &&
1139 gf_group->update_type[gf_group->index] == OVERLAY_UPDATE) ||
1140 gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE;
1141 }
David Turnere86ee0d2019-02-18 17:16:28 +00001142 frame_params.show_existing_frame &= allow_show_existing(cpi, *frame_flags);
Yunqing Wang1973f112019-10-18 15:50:04 -07001143
1144 // Reset show_existing_alt_ref decision to 0 after it is used.
1145 if (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE) {
1146 cpi->show_existing_alt_ref = 0;
1147 }
David Turnerb0c0aa32019-01-28 16:17:13 +00001148 } else {
David Turnere86ee0d2019-02-18 17:16:28 +00001149 frame_params.show_existing_frame = 0;
David Turnerb0c0aa32019-01-28 16:17:13 +00001150 }
1151
Jingning Hanbb782982019-08-15 11:28:46 -07001152 int code_arf = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +00001153 struct lookahead_entry *source = NULL;
1154 struct lookahead_entry *last_source = NULL;
David Turnere86ee0d2019-02-18 17:16:28 +00001155 if (frame_params.show_existing_frame) {
Mufaddal Chakeraac828682019-12-13 16:31:42 +05301156 source = av1_lookahead_pop(cpi->lookahead, flush, cpi->compressor_stage);
Jingning Hand392c012019-09-19 15:48:08 -07001157 frame_params.show_frame = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +00001158 } else {
Yunqing Wang699fa7f2019-10-15 17:40:46 -07001159 int show_existing_alt_ref = 0;
Jingning Hanbb782982019-08-15 11:28:46 -07001160 source = choose_frame_source(cpi, &code_arf, &flush, &last_source,
Yunqing Wang699fa7f2019-10-15 17:40:46 -07001161 &frame_params, &show_existing_alt_ref);
Yunqing Wang1973f112019-10-18 15:50:04 -07001162 if (gf_group->update_type[gf_group->index] == ARF_UPDATE)
1163 cpi->show_existing_alt_ref = show_existing_alt_ref;
David Turnerdedd8ff2019-01-23 13:59:46 +00001164 }
1165
1166 if (source == NULL) { // If no source was found, we can't encode a frame.
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001167#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +00001168 if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
1169 av1_end_first_pass(cpi); /* get last stats packet */
1170 cpi->twopass.first_pass_done = 1;
1171 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001172#endif
David Turnerdedd8ff2019-01-23 13:59:46 +00001173 return -1;
1174 }
1175
Jingning Hanbb782982019-08-15 11:28:46 -07001176 frame_input.source = code_arf ? &cpi->alt_ref_buffer : &source->img;
David Turnerdedd8ff2019-01-23 13:59:46 +00001177 frame_input.last_source = last_source != NULL ? &last_source->img : NULL;
1178 frame_input.ts_duration = source->ts_end - source->ts_start;
1179
1180 *time_stamp = source->ts_start;
1181 *time_end = source->ts_end;
1182 if (source->ts_start < cpi->first_time_stamp_ever) {
1183 cpi->first_time_stamp_ever = source->ts_start;
1184 cpi->last_end_time_stamp_seen = source->ts_start;
1185 }
1186
1187 av1_apply_encoding_flags(cpi, source->flags);
David Turnere86ee0d2019-02-18 17:16:28 +00001188 if (!frame_params.show_existing_frame)
David Turnerdedd8ff2019-01-23 13:59:46 +00001189 *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
David Turnerdedd8ff2019-01-23 13:59:46 +00001190
Jingning Hand392c012019-09-19 15:48:08 -07001191 // Shown frames and arf-overlay frames need frame-rate considering
1192 if (frame_params.show_frame) adjust_frame_rate(cpi, source);
David Turnerdedd8ff2019-01-23 13:59:46 +00001193
Jingning Hand392c012019-09-19 15:48:08 -07001194 if (!frame_params.show_existing_frame) {
David Turnerdedd8ff2019-01-23 13:59:46 +00001195 if (cpi->film_grain_table) {
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001196 cm->cur_frame->film_grain_params_present = aom_film_grain_table_lookup(
David Turnerdedd8ff2019-01-23 13:59:46 +00001197 cpi->film_grain_table, *time_stamp, *time_end, 0 /* =erase */,
1198 &cm->film_grain_params);
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001199 } else {
1200 cm->cur_frame->film_grain_params_present =
1201 cm->seq_params.film_grain_params_present;
David Turnerdedd8ff2019-01-23 13:59:46 +00001202 }
David Turnerdedd8ff2019-01-23 13:59:46 +00001203 // only one operating point supported now
Yue Chen1bc5be62018-08-24 13:57:32 -07001204 const int64_t pts64 = ticks_to_timebase_units(timestamp_ratio, *time_stamp);
David Turnerdedd8ff2019-01-23 13:59:46 +00001205 if (pts64 < 0 || pts64 > UINT32_MAX) return AOM_CODEC_ERROR;
Jingning Hand392c012019-09-19 15:48:08 -07001206 cm->frame_presentation_time = (uint32_t)pts64;
David Turnerdedd8ff2019-01-23 13:59:46 +00001207 }
1208
Marco Paniconicea99e22019-07-16 18:36:31 -07001209#if CONFIG_REALTIME_ONLY
1210 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
Marco Paniconicea99e22019-07-16 18:36:31 -07001211#else
Mufaddal Chakera3bcc72c2019-12-11 14:38:37 +05301212 if (has_no_stats_stage(cpi) && oxcf->mode == REALTIME &&
1213 oxcf->lag_in_frames == 0)
Marco Paniconicea99e22019-07-16 18:36:31 -07001214 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301215 else if (!is_stat_generation_stage(cpi))
David Turner73245762019-02-11 16:42:34 +00001216 av1_get_second_pass_params(cpi, &frame_params, *frame_flags);
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001217#endif
Jingning Hand392c012019-09-19 15:48:08 -07001218 FRAME_UPDATE_TYPE frame_update_type = get_frame_update_type(gf_group);
David Turner4f1f1812019-01-24 17:00:24 +00001219
David Turnere86ee0d2019-02-18 17:16:28 +00001220 if (frame_params.show_existing_frame &&
1221 frame_params.frame_type != KEY_FRAME) {
David Turner475a3132019-01-18 15:17:17 +00001222 // Force show-existing frames to be INTER, except forward keyframes
1223 frame_params.frame_type = INTER_FRAME;
1224 }
1225
David Turner056f7cd2019-01-07 17:48:13 +00001226 // TODO(david.turner@argondesign.com): Move all the encode strategy
1227 // (largely near av1_get_compressed_data) in here
1228
1229 // TODO(david.turner@argondesign.com): Change all the encode strategy to
1230 // modify frame_params instead of cm or cpi.
1231
David Turner04b70d82019-01-24 15:39:19 +00001232 // Per-frame encode speed. In theory this can vary, but things may have been
1233 // written assuming speed-level will not change within a sequence, so this
1234 // parameter should be used with caution.
1235 frame_params.speed = oxcf->speed;
1236
David Turnerddbff442019-01-21 14:58:42 +00001237 // Work out some encoding parameters specific to the pass:
Mufaddal Chakera3bcc72c2019-12-11 14:38:37 +05301238 if (has_no_stats_stage(cpi) && cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Sarah Parker97803fc2019-05-17 14:15:37 -07001239 av1_cyclic_refresh_update_parameters(cpi);
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301240 } else if (is_stat_generation_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001241 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&cpi->oxcf);
David Turner4f1f1812019-01-24 17:00:24 +00001242 const int kf_requested = (cm->current_frame.frame_number == 0 ||
David Turner73245762019-02-11 16:42:34 +00001243 (*frame_flags & FRAMEFLAGS_KEY));
David Turner4f1f1812019-01-24 17:00:24 +00001244 if (kf_requested && frame_update_type != OVERLAY_UPDATE &&
1245 frame_update_type != INTNL_OVERLAY_UPDATE) {
David Turnerddbff442019-01-21 14:58:42 +00001246 frame_params.frame_type = KEY_FRAME;
1247 } else {
1248 frame_params.frame_type = INTER_FRAME;
David Turnercb5e36f2019-01-17 17:15:25 +00001249 }
Hamsalekha S37cc1d12019-12-12 19:27:41 +05301250 } else if (is_stat_consumption_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001251#if CONFIG_MISMATCH_DEBUG
1252 mismatch_move_frame_idx_w();
1253#endif
1254#if TXCOEFF_COST_TIMER
1255 cm->txcoeff_cost_timer = 0;
1256 cm->txcoeff_cost_count = 0;
1257#endif
1258 }
1259
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301260 if (!is_stat_generation_stage(cpi)) set_ext_overrides(cpi, &frame_params);
David Turnerddbff442019-01-21 14:58:42 +00001261
David Turner4f1f1812019-01-24 17:00:24 +00001262 // Shown keyframes and S frames refresh all reference buffers
1263 const int force_refresh_all =
1264 ((frame_params.frame_type == KEY_FRAME && frame_params.show_frame) ||
1265 frame_params.frame_type == S_FRAME) &&
David Turnere86ee0d2019-02-18 17:16:28 +00001266 !frame_params.show_existing_frame;
David Turner4f1f1812019-01-24 17:00:24 +00001267
David Turnerfe3aecb2019-02-06 14:42:42 +00001268 av1_configure_buffer_updates(cpi, &frame_params, frame_update_type,
1269 force_refresh_all);
David Turner4f1f1812019-01-24 17:00:24 +00001270
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301271 if (!is_stat_generation_stage(cpi)) {
Marco Paniconi67142112019-07-24 15:00:31 -07001272 if (!cpi->ext_refresh_frame_flags_pending) {
Jingning Handae645a2019-08-01 10:00:11 -07001273 av1_get_ref_frames(cpi, &cpi->ref_buffer_stack);
Marco Paniconid8574e32019-08-04 21:30:12 -07001274 } else if (cpi->svc.external_ref_frame_config) {
Marco Paniconi67142112019-07-24 15:00:31 -07001275 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++)
1276 cm->remapped_ref_idx[i] = cpi->svc.ref_idx[i];
1277 }
Jingning Han0a2af4e2019-07-08 19:30:03 -07001278
David Turnerddbff442019-01-21 14:58:42 +00001279 // Work out which reference frame slots may be used.
1280 frame_params.ref_frame_flags = get_ref_frame_flags(cpi);
David Turnerddbff442019-01-21 14:58:42 +00001281
David Turnera7f133c2019-01-22 14:47:16 +00001282 frame_params.primary_ref_frame =
1283 choose_primary_ref_frame(cpi, &frame_params);
Sarah Parkere1b22012019-06-06 16:35:25 -07001284 frame_params.order_offset = get_order_offset(&cpi->gf_group, &frame_params);
David Turner6e8b4d92019-02-18 15:01:33 +00001285
Jingning Han42266ca2019-07-12 14:37:16 -07001286 frame_params.refresh_frame_flags = av1_get_refresh_frame_flags(
1287 cpi, &frame_params, frame_update_type, &cpi->ref_buffer_stack);
Jingning Hana7293932019-08-15 15:46:49 -07001288
1289 frame_params.existing_fb_idx_to_show =
1290 frame_params.show_existing_frame
Debargha Mukherjeea2074dd2019-09-04 10:03:44 -07001291 ? (frame_update_type == INTNL_OVERLAY_UPDATE
1292 ? get_ref_frame_map_idx(cm, BWDREF_FRAME)
1293 : get_ref_frame_map_idx(cm, ALTREF_FRAME))
Jingning Hana7293932019-08-15 15:46:49 -07001294 : INVALID_IDX;
David Turnera7f133c2019-01-22 14:47:16 +00001295 }
1296
David Turner73245762019-02-11 16:42:34 +00001297 // The way frame_params->remapped_ref_idx is setup is a placeholder.
David Turnerf4592292019-02-21 11:50:30 +00001298 // Currently, reference buffer assignment is done by update_ref_frame_map()
David Turner73245762019-02-11 16:42:34 +00001299 // which is called by high-level strategy AFTER encoding a frame. It modifies
1300 // cm->remapped_ref_idx. If you want to use an alternative method to
1301 // determine reference buffer assignment, just put your assignments into
1302 // frame_params->remapped_ref_idx here and they will be used when encoding
1303 // this frame. If frame_params->remapped_ref_idx is setup independently of
David Turnerf4592292019-02-21 11:50:30 +00001304 // cm->remapped_ref_idx then update_ref_frame_map() will have no effect.
David Turner73245762019-02-11 16:42:34 +00001305 memcpy(frame_params.remapped_ref_idx, cm->remapped_ref_idx,
1306 REF_FRAMES * sizeof(*cm->remapped_ref_idx));
1307
Ravi Chaudharyeeae7292019-06-26 13:32:59 +05301308 cpi->td.mb.e_mbd.delta_qindex = 0;
Yue Chen4e585cc2019-06-03 14:47:16 -07001309
1310 if (!frame_params.show_existing_frame) {
1311 cm->using_qmatrix = cpi->oxcf.using_qm;
1312 cm->min_qmlevel = cpi->oxcf.qm_minlevel;
1313 cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
Jerome Jiangd413f4a2019-09-23 14:53:03 -07001314#if !CONFIG_REALTIME_ONLY
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301315 if (oxcf->lag_in_frames > 0 && !is_stat_generation_stage(cpi)) {
Sarah Parkere1b22012019-06-06 16:35:25 -07001316 if (cpi->gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
Yue Chen4e585cc2019-06-03 14:47:16 -07001317 av1_configure_buffer_updates(cpi, &frame_params, frame_update_type, 0);
1318 av1_set_frame_size(cpi, cm->width, cm->height);
Jingning Han81d6fbb2019-07-15 10:14:13 -07001319 av1_tpl_setup_stats(cpi, &frame_params, &frame_input);
Yue Chen4e585cc2019-06-03 14:47:16 -07001320 assert(cpi->num_gf_group_show_frames == 1);
1321 }
1322 }
Jerome Jiangd413f4a2019-09-23 14:53:03 -07001323#endif
Yue Chen4e585cc2019-06-03 14:47:16 -07001324 }
1325
Cheng Chen4f666ca2019-11-18 17:05:03 -08001326 // Save unfiltered source.
1327 cpi->unfiltered_source = frame_input.source;
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001328#if CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +00001329 if (av1_encode(cpi, dest, &frame_input, &frame_params, &frame_results) !=
David Turnerddbff442019-01-21 14:58:42 +00001330 AOM_CODEC_OK) {
1331 return AOM_CODEC_ERROR;
1332 }
Cheng Chen0fcf6f82019-10-11 11:41:19 -07001333#else
1334 if (denoise_and_encode(cpi, dest, &frame_input, &frame_params, &frame_results,
1335 &code_arf) != AOM_CODEC_OK) {
1336 return AOM_CODEC_ERROR;
1337 }
1338#endif // CONFIG_REALTIME_ONLY
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301339 if (!is_stat_generation_stage(cpi))
1340 cpi->num_gf_group_show_frames += frame_params.show_frame;
David Turnerddbff442019-01-21 14:58:42 +00001341
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301342 if (!is_stat_generation_stage(cpi)) {
David Turner73245762019-02-11 16:42:34 +00001343 // First pass doesn't modify reference buffer assignment or produce frame
1344 // flags
1345 update_frame_flags(cpi, frame_flags);
Marco Paniconi8d335b72019-08-06 09:07:07 -07001346 if (!cpi->ext_refresh_frame_flags_pending) {
1347 int ref_map_index =
1348 av1_get_refresh_ref_frame_map(cm->current_frame.refresh_frame_flags);
Sarah Parkeredffc652019-10-25 16:30:32 -07001349 av1_update_ref_frame_map(cpi, frame_update_type, cm->show_existing_frame,
1350 ref_map_index, &cpi->ref_buffer_stack);
Marco Paniconi8d335b72019-08-06 09:07:07 -07001351 }
David Turner73245762019-02-11 16:42:34 +00001352 }
1353
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001354#if !CONFIG_REALTIME_ONLY
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301355 if (!is_stat_generation_stage(cpi)) {
David Turnerddbff442019-01-21 14:58:42 +00001356#if TXCOEFF_COST_TIMER
1357 cm->cum_txcoeff_cost_timer += cm->txcoeff_cost_timer;
1358 fprintf(stderr,
1359 "\ntxb coeff cost block number: %ld, frame time: %ld, cum time %ld "
1360 "in us\n",
1361 cm->txcoeff_cost_count, cm->txcoeff_cost_timer,
1362 cm->cum_txcoeff_cost_timer);
1363#endif
1364 av1_twopass_postencode_update(cpi);
1365 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001366#endif // !CONFIG_REALTIME_ONLY
David Turnerddbff442019-01-21 14:58:42 +00001367
Mufaddal Chakerae7326122019-12-04 14:49:09 +05301368 if (!is_stat_generation_stage(cpi)) {
David Turnera7f133c2019-01-22 14:47:16 +00001369 update_fb_of_context_type(cpi, &frame_params, cpi->fb_of_context_type);
David Turner73245762019-02-11 16:42:34 +00001370 set_additional_frame_flags(cm, frame_flags);
David Turnerddbff442019-01-21 14:58:42 +00001371 update_rc_counts(cpi);
David Turner056f7cd2019-01-07 17:48:13 +00001372 }
1373
David Turner1539bb02019-01-24 15:28:13 +00001374 // Unpack frame_results:
David Turner056f7cd2019-01-07 17:48:13 +00001375 *size = frame_results.size;
1376
David Turner1539bb02019-01-24 15:28:13 +00001377 // Leave a signal for a higher level caller about if this frame is droppable
1378 if (*size > 0) {
1379 cpi->droppable = is_frame_droppable(cpi);
1380 }
1381
Marco Paniconi5b1e4732019-08-08 18:57:53 -07001382 if (cpi->use_svc) av1_save_layer_context(cpi);
1383
David Turner056f7cd2019-01-07 17:48:13 +00001384 return AOM_CODEC_OK;
1385}