blob: d8c99ec2e9a17d074d7ffd4f96cb1a5132b14b88 [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;
Urvang Joshif70375a2019-03-22 23:30:19 -070047 cpi->rc.is_src_frame_internal_arf = 0;
David Turnerce9b5902019-01-23 17:25:47 +000048
49 switch (type) {
50 case KF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000051 frame_params->refresh_last_frame = 1;
52 frame_params->refresh_golden_frame = 1;
53 frame_params->refresh_bwd_ref_frame = 1;
54 frame_params->refresh_alt2_ref_frame = 1;
55 frame_params->refresh_alt_ref_frame = 1;
David Turnerce9b5902019-01-23 17:25:47 +000056 break;
57
58 case LF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000059 frame_params->refresh_last_frame = 1;
60 frame_params->refresh_golden_frame = 0;
61 frame_params->refresh_bwd_ref_frame = 0;
62 frame_params->refresh_alt2_ref_frame = 0;
63 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000064 break;
65
66 case GF_UPDATE:
67 // TODO(zoeliu): To further investigate whether 'refresh_last_frame' is
68 // needed.
David Turnerfe3aecb2019-02-06 14:42:42 +000069 frame_params->refresh_last_frame = 1;
70 frame_params->refresh_golden_frame = 1;
71 frame_params->refresh_bwd_ref_frame = 0;
72 frame_params->refresh_alt2_ref_frame = 0;
73 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000074 break;
75
76 case OVERLAY_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000077 frame_params->refresh_last_frame = 0;
78 frame_params->refresh_golden_frame = 1;
79 frame_params->refresh_bwd_ref_frame = 0;
80 frame_params->refresh_alt2_ref_frame = 0;
81 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000082
83 cpi->rc.is_src_frame_alt_ref = 1;
84 break;
85
86 case ARF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000087 frame_params->refresh_last_frame = 0;
88 frame_params->refresh_golden_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +000089 // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
David Turnerfe3aecb2019-02-06 14:42:42 +000090 frame_params->refresh_bwd_ref_frame = 0;
91 frame_params->refresh_alt2_ref_frame = 0;
92 frame_params->refresh_alt_ref_frame = 1;
David Turnerce9b5902019-01-23 17:25:47 +000093 break;
94
David Turnerce9b5902019-01-23 17:25:47 +000095 case INTNL_OVERLAY_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +000096 frame_params->refresh_last_frame = 1;
97 frame_params->refresh_golden_frame = 0;
98 frame_params->refresh_bwd_ref_frame = 0;
99 frame_params->refresh_alt2_ref_frame = 0;
100 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +0000101
102 cpi->rc.is_src_frame_alt_ref = 1;
Urvang Joshif70375a2019-03-22 23:30:19 -0700103 cpi->rc.is_src_frame_internal_arf = 1;
David Turnerce9b5902019-01-23 17:25:47 +0000104 break;
105
106 case INTNL_ARF_UPDATE:
David Turnerfe3aecb2019-02-06 14:42:42 +0000107 frame_params->refresh_last_frame = 0;
108 frame_params->refresh_golden_frame = 0;
Sarah Parker97803fc2019-05-17 14:15:37 -0700109 if (cpi->oxcf.pass != 1) {
David Turnerfe3aecb2019-02-06 14:42:42 +0000110 frame_params->refresh_bwd_ref_frame = 1;
111 frame_params->refresh_alt2_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +0000112 } else {
David Turnerfe3aecb2019-02-06 14:42:42 +0000113 frame_params->refresh_bwd_ref_frame = 0;
114 frame_params->refresh_alt2_ref_frame = 1;
David Turnerce9b5902019-01-23 17:25:47 +0000115 }
David Turnerfe3aecb2019-02-06 14:42:42 +0000116 frame_params->refresh_alt_ref_frame = 0;
David Turnerce9b5902019-01-23 17:25:47 +0000117 break;
118
119 default: assert(0); break;
120 }
David Turner4f1f1812019-01-24 17:00:24 +0000121
122 if (cpi->ext_refresh_frame_flags_pending &&
123 (cpi->oxcf.pass == 0 || cpi->oxcf.pass == 2)) {
David Turnerfe3aecb2019-02-06 14:42:42 +0000124 frame_params->refresh_last_frame = cpi->ext_refresh_last_frame;
125 frame_params->refresh_golden_frame = cpi->ext_refresh_golden_frame;
126 frame_params->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
127 frame_params->refresh_bwd_ref_frame = cpi->ext_refresh_bwd_ref_frame;
128 frame_params->refresh_alt2_ref_frame = cpi->ext_refresh_alt2_ref_frame;
David Turner4f1f1812019-01-24 17:00:24 +0000129 }
130
131 if (force_refresh_all) {
David Turnerfe3aecb2019-02-06 14:42:42 +0000132 frame_params->refresh_last_frame = 1;
133 frame_params->refresh_golden_frame = 1;
134 frame_params->refresh_bwd_ref_frame = 1;
135 frame_params->refresh_alt2_ref_frame = 1;
136 frame_params->refresh_alt_ref_frame = 1;
David Turner4f1f1812019-01-24 17:00:24 +0000137 }
David Turnerce9b5902019-01-23 17:25:47 +0000138}
139
David Turner1539bb02019-01-24 15:28:13 +0000140static void set_additional_frame_flags(const AV1_COMMON *const cm,
141 unsigned int *const frame_flags) {
142 if (frame_is_intra_only(cm)) *frame_flags |= FRAMEFLAGS_INTRAONLY;
143 if (frame_is_sframe(cm)) *frame_flags |= FRAMEFLAGS_SWITCH;
144 if (cm->error_resilient_mode) *frame_flags |= FRAMEFLAGS_ERROR_RESILIENT;
145}
146
147static INLINE void update_keyframe_counters(AV1_COMP *cpi) {
Urvang Joshi6ce7fbc2019-03-22 15:24:21 -0700148 if (cpi->common.show_frame) {
David Turner1539bb02019-01-24 15:28:13 +0000149 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref ||
150 cpi->common.current_frame.frame_type == KEY_FRAME) {
151 // If this is a show_existing_frame with a source other than altref,
152 // or if it is not a displayed forward keyframe, the keyframe update
153 // counters were incremented when it was originally encoded.
154 cpi->rc.frames_since_key++;
155 cpi->rc.frames_to_key--;
156 }
157 }
158}
159
160static INLINE int is_frame_droppable(const AV1_COMP *const cpi) {
Marco Paniconi91a50022019-08-01 18:56:39 -0700161 if (cpi->ext_refresh_frame_flags_pending)
162 return !(cpi->ext_refresh_alt_ref_frame ||
163 cpi->ext_refresh_alt2_ref_frame ||
164 cpi->ext_refresh_bwd_ref_frame || cpi->ext_refresh_golden_frame ||
165 cpi->ext_refresh_last_frame);
166 else
167 return !(cpi->refresh_alt_ref_frame || cpi->refresh_alt2_ref_frame ||
168 cpi->refresh_bwd_ref_frame || cpi->refresh_golden_frame ||
169 cpi->refresh_last_frame);
David Turner1539bb02019-01-24 15:28:13 +0000170}
171
172static INLINE void update_frames_till_gf_update(AV1_COMP *cpi) {
173 // TODO(weitinglin): Updating this counter for is_frame_droppable
174 // is a work-around to handle the condition when a frame is drop.
175 // We should fix the cpi->common.show_frame flag
176 // instead of checking the other condition to update the counter properly.
177 if (cpi->common.show_frame || is_frame_droppable(cpi)) {
178 // Decrement count down till next gf
179 if (cpi->rc.frames_till_gf_update_due > 0)
180 cpi->rc.frames_till_gf_update_due--;
181 }
182}
183
Sarah Parker97803fc2019-05-17 14:15:37 -0700184static INLINE void update_gf_group_index(AV1_COMP *cpi) {
David Turner1539bb02019-01-24 15:28:13 +0000185 // Increment the gf group index ready for the next frame. If this is
186 // a show_existing_frame with a source other than altref, or if it is not
187 // a displayed forward keyframe, the index was incremented when it was
188 // originally encoded.
189 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref ||
190 cpi->common.current_frame.frame_type == KEY_FRAME) {
Sarah Parkere1b22012019-06-06 16:35:25 -0700191 ++cpi->gf_group.index;
David Turner1539bb02019-01-24 15:28:13 +0000192 }
193}
194
195static void update_rc_counts(AV1_COMP *cpi) {
196 update_keyframe_counters(cpi);
197 update_frames_till_gf_update(cpi);
Sarah Parker97803fc2019-05-17 14:15:37 -0700198 update_gf_group_index(cpi);
David Turner1539bb02019-01-24 15:28:13 +0000199}
200
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700201// Get update type of the current frame.
202static INLINE FRAME_UPDATE_TYPE get_frame_update_type(const AV1_COMP *cpi) {
Sarah Parkere1b22012019-06-06 16:35:25 -0700203 const GF_GROUP *const gf_group = &cpi->gf_group;
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700204 if (gf_group->size == 0) {
205 // Special case 1: happens at the first frame of a video.
206 return KF_UPDATE;
207 }
208 if (gf_group->index == gf_group->size) {
209 // Special case 2: happens at the start of next GF group, or at the end of
210 // the key-frame group. So, not marked in gf_group->update_type array, but
211 // can be inferred implicitly.
212 return cpi->rc.source_alt_ref_active ? OVERLAY_UPDATE : GF_UPDATE;
213 }
214 // General case.
215 return gf_group->update_type[gf_group->index];
216}
217
218// Get ARF update index for the current frame.
219// Returns 1 for internal ARF, and 0 otherwise (including top-level ARF).
220static INLINE int get_arf_update_idx(const GF_GROUP *const gf_group) {
221 if (gf_group->index == gf_group->size) {
222 // Special case: happens at the start of a video, or at the start of next GF
223 // group, or at the end of the key-frame group. So, not marked in
224 // gf_group->arf_update_idx array, but can implicitly inferred be a
225 // top-level ARF.
226 return 0;
227 }
228 // General case.
229 return (gf_group->arf_update_idx[gf_group->index] > 0);
230}
231
232// Note: the parameters related to OVERLAY_UPDATE will be taken care of in
233// av1_get_second_pass_params().
David Turnere86ee0d2019-02-18 17:16:28 +0000234static void check_show_existing_frame(AV1_COMP *const cpi,
235 EncodeFrameParams *const frame_params) {
Sarah Parkere1b22012019-06-06 16:35:25 -0700236 const GF_GROUP *const gf_group = &cpi->gf_group;
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700237 assert(gf_group->index <= gf_group->size);
Jingning Han6cb30912019-08-01 09:33:37 -0700238 (void)gf_group;
David Turner1539bb02019-01-24 15:28:13 +0000239 AV1_COMMON *const cm = &cpi->common;
David Turner1539bb02019-01-24 15:28:13 +0000240 if (cm->show_existing_frame == 1) {
David Turnere86ee0d2019-02-18 17:16:28 +0000241 frame_params->show_existing_frame = 0;
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700242 } else {
243 const FRAME_UPDATE_TYPE frame_update_type = get_frame_update_type(cpi);
Jingning Han6cb30912019-08-01 09:33:37 -0700244 if (frame_update_type == INTNL_OVERLAY_UPDATE) {
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700245 frame_params->show_existing_frame = 1;
246 frame_params->existing_fb_idx_to_show =
Jingning Han6cb30912019-08-01 09:33:37 -0700247 get_ref_frame_map_idx(cm, BWDREF_FRAME);
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700248
249 } else {
250 frame_params->show_existing_frame = 0;
251 }
David Turner1539bb02019-01-24 15:28:13 +0000252 }
David Turner1539bb02019-01-24 15:28:13 +0000253}
254
David Turner07dbd8e2019-01-08 17:16:25 +0000255static void set_ext_overrides(AV1_COMP *const cpi,
256 EncodeFrameParams *const frame_params) {
257 // Overrides the defaults with the externally supplied values with
258 // av1_update_reference() and av1_update_entropy() calls
259 // Note: The overrides are valid only for the next frame passed
260 // to av1_encode_lowlevel()
261
262 AV1_COMMON *const cm = &cpi->common;
263
264 if (cpi->ext_use_s_frame) {
David Turner475a3132019-01-18 15:17:17 +0000265 frame_params->frame_type = S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000266 }
David Turner07dbd8e2019-01-08 17:16:25 +0000267
268 if (cpi->ext_refresh_frame_context_pending) {
269 cm->refresh_frame_context = cpi->ext_refresh_frame_context;
270 cpi->ext_refresh_frame_context_pending = 0;
271 }
David Turner07dbd8e2019-01-08 17:16:25 +0000272 cm->allow_ref_frame_mvs = cpi->ext_use_ref_frame_mvs;
273
274 frame_params->error_resilient_mode = cpi->ext_use_error_resilient;
275 // A keyframe is already error resilient and keyframes with
276 // error_resilient_mode interferes with the use of show_existing_frame
277 // when forward reference keyframes are enabled.
David Turner475a3132019-01-18 15:17:17 +0000278 frame_params->error_resilient_mode &= frame_params->frame_type != KEY_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000279 // For bitstream conformance, s-frames must be error-resilient
David Turner475a3132019-01-18 15:17:17 +0000280 frame_params->error_resilient_mode |= frame_params->frame_type == S_FRAME;
David Turner07dbd8e2019-01-08 17:16:25 +0000281}
282
283static int get_ref_frame_flags(const AV1_COMP *const cpi) {
284 const AV1_COMMON *const cm = &cpi->common;
285
286 const RefCntBuffer *last_buf = get_ref_frame_buf(cm, LAST_FRAME);
287 const RefCntBuffer *last2_buf = get_ref_frame_buf(cm, LAST2_FRAME);
288 const RefCntBuffer *last3_buf = get_ref_frame_buf(cm, LAST3_FRAME);
289 const RefCntBuffer *golden_buf = get_ref_frame_buf(cm, GOLDEN_FRAME);
290 const RefCntBuffer *bwd_buf = get_ref_frame_buf(cm, BWDREF_FRAME);
291 const RefCntBuffer *alt2_buf = get_ref_frame_buf(cm, ALTREF2_FRAME);
292 const RefCntBuffer *alt_buf = get_ref_frame_buf(cm, ALTREF_FRAME);
293
294 // No.1 Priority: LAST_FRAME
295 const int last2_is_last = (last2_buf == last_buf);
296 const int last3_is_last = (last3_buf == last_buf);
297 const int gld_is_last = (golden_buf == last_buf);
298 const int bwd_is_last = (bwd_buf == last_buf);
299 const int alt2_is_last = (alt2_buf == last_buf);
300 const int alt_is_last = (alt_buf == last_buf);
301
302 // No.2 Priority: ALTREF_FRAME
303 const int last2_is_alt = (last2_buf == alt_buf);
304 const int last3_is_alt = (last3_buf == alt_buf);
305 const int gld_is_alt = (golden_buf == alt_buf);
306 const int bwd_is_alt = (bwd_buf == alt_buf);
307 const int alt2_is_alt = (alt2_buf == alt_buf);
308
309 // No.3 Priority: LAST2_FRAME
310 const int last3_is_last2 = (last3_buf == last2_buf);
311 const int gld_is_last2 = (golden_buf == last2_buf);
312 const int bwd_is_last2 = (bwd_buf == last2_buf);
313 const int alt2_is_last2 = (alt2_buf == last2_buf);
314
315 // No.4 Priority: LAST3_FRAME
316 const int gld_is_last3 = (golden_buf == last3_buf);
317 const int bwd_is_last3 = (bwd_buf == last3_buf);
318 const int alt2_is_last3 = (alt2_buf == last3_buf);
319
320 // No.5 Priority: GOLDEN_FRAME
321 const int bwd_is_gld = (bwd_buf == golden_buf);
322 const int alt2_is_gld = (alt2_buf == golden_buf);
323
324 // No.6 Priority: BWDREF_FRAME
325 const int alt2_is_bwd = (alt2_buf == bwd_buf);
326
327 // No.7 Priority: ALTREF2_FRAME
328
329 // cpi->ext_ref_frame_flags allows certain reference types to be disabled
330 // by the external interface. These are set by av1_apply_encoding_flags().
331 // Start with what the external interface allows, then suppress any reference
332 // types which we have found to be duplicates.
333
334 int flags = cpi->ext_ref_frame_flags;
335
336 if (cpi->rc.frames_till_gf_update_due == INT_MAX) flags &= ~AOM_GOLD_FLAG;
337
338 if (alt_is_last) flags &= ~AOM_ALT_FLAG;
339
340 if (last2_is_last || last2_is_alt) flags &= ~AOM_LAST2_FLAG;
341
342 if (last3_is_last || last3_is_alt || last3_is_last2) flags &= ~AOM_LAST3_FLAG;
343
Fyodor Kyslov84abaea2019-06-25 14:44:14 -0700344 if (gld_is_last || gld_is_last2 || gld_is_last3) {
David Turner07dbd8e2019-01-08 17:16:25 +0000345 flags &= ~AOM_GOLD_FLAG;
Fyodor Kyslov84abaea2019-06-25 14:44:14 -0700346 }
347
348 if (!cpi->sf.use_fast_nonrd_pick_mode && gld_is_alt) {
349 flags &= ~AOM_GOLD_FLAG;
350 }
David Turner07dbd8e2019-01-08 17:16:25 +0000351
352 if ((bwd_is_last || bwd_is_alt || bwd_is_last2 || bwd_is_last3 || bwd_is_gld))
353 flags &= ~AOM_BWD_FLAG;
354
355 if ((alt2_is_last || alt2_is_alt || alt2_is_last2 || alt2_is_last3 ||
356 alt2_is_gld || alt2_is_bwd))
357 flags &= ~AOM_ALT2_FLAG;
358
359 return flags;
360}
361
David Turnera7f133c2019-01-22 14:47:16 +0000362static int get_current_frame_ref_type(
363 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
David Turnera7f133c2019-01-22 14:47:16 +0000364 // We choose the reference "type" of this frame from the flags which indicate
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700365 // which reference frames will be refreshed by it. More than one of these
366 // flags may be set, so the order here implies an order of precedence. This is
367 // just used to choose the primary_ref_frame (as the most recent reference
368 // buffer of the same reference-type as the current frame)
David Turnera7f133c2019-01-22 14:47:16 +0000369
Jingning Han370d1162019-07-03 10:24:03 -0700370 (void)frame_params;
371 // TODO(jingning): This table should be a lot simpler with the new
372 // ARF system in place. Keep frame_params for the time being as we are
373 // still evaluating a few design options.
374 switch (cpi->gf_group.layer_depth[cpi->gf_group.index]) {
375 case 0: return 0;
376 case 1: return 1;
377 case MAX_ARF_LAYERS:
378 case MAX_ARF_LAYERS + 1: return 4;
379 default: return 7;
380 }
David Turnera7f133c2019-01-22 14:47:16 +0000381}
382
383static int choose_primary_ref_frame(
384 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
385 const AV1_COMMON *const cm = &cpi->common;
386
387 const int intra_only = frame_params->frame_type == KEY_FRAME ||
388 frame_params->frame_type == INTRA_ONLY_FRAME;
389 if (intra_only || frame_params->error_resilient_mode ||
390 cpi->ext_use_primary_ref_none) {
391 return PRIMARY_REF_NONE;
392 }
393
394 // Find the most recent reference frame with the same reference type as the
395 // current frame
Jingning Han370d1162019-07-03 10:24:03 -0700396 FRAME_CONTEXT_INDEX current_ref_type =
David Turnera7f133c2019-01-22 14:47:16 +0000397 get_current_frame_ref_type(cpi, frame_params);
398 int wanted_fb = cpi->fb_of_context_type[current_ref_type];
399
400 int primary_ref_frame = PRIMARY_REF_NONE;
401 for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
402 if (get_ref_frame_map_idx(cm, ref_frame) == wanted_fb) {
403 primary_ref_frame = ref_frame - LAST_FRAME;
404 }
405 }
Jingning Han370d1162019-07-03 10:24:03 -0700406
David Turnera7f133c2019-01-22 14:47:16 +0000407 return primary_ref_frame;
408}
409
410static void update_fb_of_context_type(
411 const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params,
412 int *const fb_of_context_type) {
413 const AV1_COMMON *const cm = &cpi->common;
Jingning Han370d1162019-07-03 10:24:03 -0700414 const int current_frame_ref_type =
415 get_current_frame_ref_type(cpi, frame_params);
David Turnera7f133c2019-01-22 14:47:16 +0000416
417 if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
418 cpi->ext_use_primary_ref_none) {
419 for (int i = 0; i < REF_FRAMES; i++) {
420 fb_of_context_type[i] = -1;
421 }
Jingning Han370d1162019-07-03 10:24:03 -0700422 fb_of_context_type[current_frame_ref_type] =
David Turnera7f133c2019-01-22 14:47:16 +0000423 cm->show_frame ? get_ref_frame_map_idx(cm, GOLDEN_FRAME)
424 : get_ref_frame_map_idx(cm, ALTREF_FRAME);
425 }
426
427 if (!encode_show_existing_frame(cm)) {
428 // Refresh fb_of_context_type[]: see encoder.h for explanation
David Turnera7f133c2019-01-22 14:47:16 +0000429 if (cm->current_frame.frame_type == KEY_FRAME) {
430 // All ref frames are refreshed, pick one that will live long enough
Jingning Han370d1162019-07-03 10:24:03 -0700431 fb_of_context_type[current_frame_ref_type] = 0;
David Turnera7f133c2019-01-22 14:47:16 +0000432 } else {
433 // If more than one frame is refreshed, it doesn't matter which one we
434 // pick so pick the first. LST sometimes doesn't refresh any: this is ok
Jingning Han370d1162019-07-03 10:24:03 -0700435
David Turnera7f133c2019-01-22 14:47:16 +0000436 for (int i = 0; i < REF_FRAMES; i++) {
437 if (cm->current_frame.refresh_frame_flags & (1 << i)) {
438 fb_of_context_type[current_frame_ref_type] = i;
439 break;
440 }
441 }
442 }
443 }
444}
445
David Turnere86ee0d2019-02-18 17:16:28 +0000446static int get_order_offset(const GF_GROUP *const gf_group,
David Turnerdedd8ff2019-01-23 13:59:46 +0000447 const EncodeFrameParams *const frame_params) {
David Turnera7f133c2019-01-22 14:47:16 +0000448 // shown frame by definition has order offset 0
449 // show_existing_frame ignores order_offset and simply takes the order_hint
450 // from the reference frame being shown.
David Turnere86ee0d2019-02-18 17:16:28 +0000451 if (frame_params->show_frame || frame_params->show_existing_frame) return 0;
David Turnera7f133c2019-01-22 14:47:16 +0000452
David Turnera7f133c2019-01-22 14:47:16 +0000453 const int arf_offset =
454 AOMMIN((MAX_GF_INTERVAL - 1), gf_group->arf_src_offset[gf_group->index]);
Urvang Joshi6ce7fbc2019-03-22 15:24:21 -0700455 return AOMMIN((MAX_GF_INTERVAL - 1), arf_offset);
David Turnera7f133c2019-01-22 14:47:16 +0000456}
457
David Turnerdedd8ff2019-01-23 13:59:46 +0000458static void adjust_frame_rate(AV1_COMP *cpi,
459 const struct lookahead_entry *source) {
460 int64_t this_duration;
461 int step = 0;
462
463 // Clear down mmx registers
464 aom_clear_system_state();
465
466 if (source->ts_start == cpi->first_time_stamp_ever) {
467 this_duration = source->ts_end - source->ts_start;
468 step = 1;
469 } else {
470 int64_t last_duration =
471 cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen;
472
473 this_duration = source->ts_end - cpi->last_end_time_stamp_seen;
474
475 // do a step update if the duration changes by 10%
476 if (last_duration)
477 step = (int)((this_duration - last_duration) * 10 / last_duration);
478 }
479
480 if (this_duration) {
481 if (step) {
482 av1_new_framerate(cpi, 10000000.0 / this_duration);
483 } else {
484 // Average this frame's rate into the last second's average
485 // frame rate. If we haven't seen 1 second yet, then average
486 // over the whole interval seen.
487 const double interval = AOMMIN(
488 (double)(source->ts_end - cpi->first_time_stamp_ever), 10000000.0);
489 double avg_duration = 10000000.0 / cpi->framerate;
490 avg_duration *= (interval - avg_duration + this_duration);
491 avg_duration /= interval;
492
493 av1_new_framerate(cpi, 10000000.0 / avg_duration);
494 }
495 }
496 cpi->last_time_stamp_seen = source->ts_start;
497 cpi->last_end_time_stamp_seen = source->ts_end;
498}
499
Urvang Joshif70375a2019-03-22 23:30:19 -0700500// If this is an alt-ref, returns the offset of the source frame used
501// as the arf midpoint. Otherwise, returns 0.
David Turnerdedd8ff2019-01-23 13:59:46 +0000502static int get_arf_src_index(AV1_COMP *cpi) {
503 RATE_CONTROL *const rc = &cpi->rc;
504 int arf_src_index = 0;
Sarah Parker97803fc2019-05-17 14:15:37 -0700505 if (cpi->oxcf.pass != 1) {
Sarah Parkere1b22012019-06-06 16:35:25 -0700506 const GF_GROUP *const gf_group = &cpi->gf_group;
Urvang Joshi2e4aaf22019-05-08 11:38:00 -0700507 if (get_frame_update_type(cpi) == ARF_UPDATE) {
Urvang Joshif70375a2019-03-22 23:30:19 -0700508 assert(is_altref_enabled(cpi));
509 arf_src_index = gf_group->arf_src_offset[gf_group->index];
David Turnerdedd8ff2019-01-23 13:59:46 +0000510 }
Urvang Joshif70375a2019-03-22 23:30:19 -0700511 } else if (rc->source_alt_ref_pending) {
512 arf_src_index = rc->frames_till_gf_update_due;
David Turnerdedd8ff2019-01-23 13:59:46 +0000513 }
514 return arf_src_index;
515}
516
Urvang Joshif70375a2019-03-22 23:30:19 -0700517// If this is an internal alt-ref, returns the offset of the source frame used
518// as the internal arf midpoint. Otherwise, returns 0.
519static int get_internal_arf_src_index(AV1_COMP *cpi) {
520 int internal_arf_src_index = 0;
Sarah Parker97803fc2019-05-17 14:15:37 -0700521 if (cpi->oxcf.pass != 1) {
Sarah Parkere1b22012019-06-06 16:35:25 -0700522 const GF_GROUP *const gf_group = &cpi->gf_group;
Urvang Joshif70375a2019-03-22 23:30:19 -0700523 if (gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE) {
524 assert(is_altref_enabled(cpi) && cpi->internal_altref_allowed);
525 internal_arf_src_index = gf_group->arf_src_offset[gf_group->index];
David Turnerdedd8ff2019-01-23 13:59:46 +0000526 }
527 }
Urvang Joshif70375a2019-03-22 23:30:19 -0700528 return internal_arf_src_index;
David Turnerdedd8ff2019-01-23 13:59:46 +0000529}
530
531// Called if this frame is an ARF or ARF2. Also handles forward-keyframes
532// For an ARF set arf2=0, for ARF2 set arf2=1
533// temporal_filtered is set to 1 if we temporally filter the ARF frame, so that
534// the correct post-filter buffer can be used.
535static struct lookahead_entry *setup_arf_or_arf2(
536 AV1_COMP *const cpi, const int arf_src_index, const int arf2,
537 int *temporal_filtered, EncodeFrameParams *const frame_params) {
538 AV1_COMMON *const cm = &cpi->common;
539 RATE_CONTROL *const rc = &cpi->rc;
Jerome Jiang71647472019-05-30 12:01:57 -0700540#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +0000541 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Jerome Jiang71647472019-05-30 12:01:57 -0700542#endif
David Turnerdedd8ff2019-01-23 13:59:46 +0000543
544 assert(arf_src_index <= rc->frames_to_key);
545 *temporal_filtered = 0;
546
547 struct lookahead_entry *source =
548 av1_lookahead_peek(cpi->lookahead, arf_src_index);
549
550 if (source != NULL) {
551 cm->showable_frame = 1;
552 cpi->alt_ref_source = source;
553
554 // When arf_src_index == rc->frames_to_key, it indicates a fwd_kf
555 if (!arf2 && arf_src_index == rc->frames_to_key) {
556 // Skip temporal filtering and mark as intra_only if we have a fwd_kf
David Turnerdedd8ff2019-01-23 13:59:46 +0000557 cpi->no_show_kf = 1;
558 } else {
Jerome Jiang71647472019-05-30 12:01:57 -0700559#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +0000560 if (oxcf->arnr_max_frames > 0) {
561 // Produce the filtered ARF frame.
562 av1_temporal_filter(cpi, arf_src_index);
563 aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
564 *temporal_filtered = 1;
565 }
Jerome Jiang71647472019-05-30 12:01:57 -0700566#endif
David Turnerdedd8ff2019-01-23 13:59:46 +0000567 }
568 frame_params->show_frame = 0;
David Turnerdedd8ff2019-01-23 13:59:46 +0000569 }
570 rc->source_alt_ref_pending = 0;
571 return source;
572}
573
574// Determine whether there is a forced keyframe pending in the lookahead buffer
575static int is_forced_keyframe_pending(struct lookahead_ctx *lookahead,
576 const int up_to_index) {
577 for (int i = 0; i <= up_to_index; i++) {
578 const struct lookahead_entry *e = av1_lookahead_peek(lookahead, i);
579 if (e == NULL) {
580 // We have reached the end of the lookahead buffer and not early-returned
581 // so there isn't a forced key-frame pending.
582 return 0;
583 } else if (e->flags == AOM_EFLAG_FORCE_KF) {
584 return 1;
585 } else {
586 continue;
587 }
588 }
589 return 0; // Never reached
590}
591
Urvang Joshif70375a2019-03-22 23:30:19 -0700592// Check if we should encode an ARF or internal ARF. If not, try a LAST
David Turnerdedd8ff2019-01-23 13:59:46 +0000593// Do some setup associated with the chosen source
David Turner4f1f1812019-01-24 17:00:24 +0000594// temporal_filtered, flush, and frame_update_type are outputs.
David Turnerdedd8ff2019-01-23 13:59:46 +0000595// Return the frame source, or NULL if we couldn't find one
Yaowu Xufac3d862019-04-26 15:43:03 -0700596static struct lookahead_entry *choose_frame_source(
David Turnerdedd8ff2019-01-23 13:59:46 +0000597 AV1_COMP *const cpi, int *const temporal_filtered, int *const flush,
David Turner4f1f1812019-01-24 17:00:24 +0000598 struct lookahead_entry **last_source, FRAME_UPDATE_TYPE *frame_update_type,
David Turnerdedd8ff2019-01-23 13:59:46 +0000599 EncodeFrameParams *const frame_params) {
600 AV1_COMMON *const cm = &cpi->common;
601 struct lookahead_entry *source = NULL;
602 *temporal_filtered = 0;
603
604 // Should we encode an alt-ref frame.
605 int arf_src_index = get_arf_src_index(cpi);
606 if (arf_src_index &&
607 is_forced_keyframe_pending(cpi->lookahead, arf_src_index)) {
608 arf_src_index = 0;
609 *flush = 1;
610 }
611
612 if (arf_src_index) {
613 source = setup_arf_or_arf2(cpi, arf_src_index, 0, temporal_filtered,
614 frame_params);
David Turner4f1f1812019-01-24 17:00:24 +0000615 *frame_update_type = ARF_UPDATE;
David Turnerdedd8ff2019-01-23 13:59:46 +0000616 }
617
Urvang Joshif70375a2019-03-22 23:30:19 -0700618 // Should we encode an internal Alt-ref frame (mutually exclusive to ARF)
619 arf_src_index = get_internal_arf_src_index(cpi);
David Turnerdedd8ff2019-01-23 13:59:46 +0000620 if (arf_src_index &&
621 is_forced_keyframe_pending(cpi->lookahead, arf_src_index)) {
622 arf_src_index = 0;
623 *flush = 1;
624 }
625
626 if (arf_src_index) {
627 source = setup_arf_or_arf2(cpi, arf_src_index, 1, temporal_filtered,
628 frame_params);
David Turner4f1f1812019-01-24 17:00:24 +0000629 *frame_update_type = INTNL_ARF_UPDATE;
David Turnerdedd8ff2019-01-23 13:59:46 +0000630 }
631
David Turnerdedd8ff2019-01-23 13:59:46 +0000632 if (!source) {
633 // Get last frame source.
634 if (cm->current_frame.frame_number > 0) {
635 *last_source = av1_lookahead_peek(cpi->lookahead, -1);
636 }
637 // Read in the source frame.
638 source = av1_lookahead_pop(cpi->lookahead, *flush);
David Turner4f1f1812019-01-24 17:00:24 +0000639 if (source == NULL) return NULL;
640 *frame_update_type = LF_UPDATE; // Default update type
641 frame_params->show_frame = 1;
David Turnerdedd8ff2019-01-23 13:59:46 +0000642
David Turner4f1f1812019-01-24 17:00:24 +0000643 // Check to see if the frame should be encoded as an arf overlay.
644 if (cpi->alt_ref_source == source) {
645 *frame_update_type = OVERLAY_UPDATE;
646 cpi->alt_ref_source = NULL;
David Turnerdedd8ff2019-01-23 13:59:46 +0000647 }
648 }
649 return source;
650}
651
David Turnerb0c0aa32019-01-28 16:17:13 +0000652// Don't allow a show_existing_frame to coincide with an error resilient or
653// S-Frame. An exception can be made in the case of a keyframe, since it does
654// not depend on any previous frames.
David Turner73245762019-02-11 16:42:34 +0000655static int allow_show_existing(const AV1_COMP *const cpi,
656 unsigned int frame_flags) {
David Turnerb0c0aa32019-01-28 16:17:13 +0000657 if (cpi->common.current_frame.frame_number == 0) return 0;
658
659 const struct lookahead_entry *lookahead_src =
660 av1_lookahead_peek(cpi->lookahead, 0);
661 if (lookahead_src == NULL) return 1;
662
663 const int is_error_resilient =
664 cpi->oxcf.error_resilient_mode ||
665 (lookahead_src->flags & AOM_EFLAG_ERROR_RESILIENT);
666 const int is_s_frame =
667 cpi->oxcf.s_frame_mode || (lookahead_src->flags & AOM_EFLAG_SET_S_FRAME);
668 const int is_key_frame =
David Turner73245762019-02-11 16:42:34 +0000669 (cpi->rc.frames_to_key == 0) || (frame_flags & FRAMEFLAGS_KEY);
David Turnerb0c0aa32019-01-28 16:17:13 +0000670 return !(is_error_resilient || is_s_frame) || is_key_frame;
671}
672
David Turner73245762019-02-11 16:42:34 +0000673// Update frame_flags to tell the encoder's caller what sort of frame was
674// encoded.
675static void update_frame_flags(AV1_COMP *cpi, unsigned int *frame_flags) {
676 if (encode_show_existing_frame(&cpi->common)) {
677 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
678 *frame_flags &= ~FRAMEFLAGS_BWDREF;
679 *frame_flags &= ~FRAMEFLAGS_ALTREF;
680 *frame_flags &= ~FRAMEFLAGS_KEY;
681 return;
682 }
683
684 if (cpi->refresh_golden_frame == 1) {
685 *frame_flags |= FRAMEFLAGS_GOLDEN;
686 } else {
687 *frame_flags &= ~FRAMEFLAGS_GOLDEN;
688 }
689
690 if (cpi->refresh_alt_ref_frame == 1) {
691 *frame_flags |= FRAMEFLAGS_ALTREF;
692 } else {
693 *frame_flags &= ~FRAMEFLAGS_ALTREF;
694 }
695
696 if (cpi->refresh_bwd_ref_frame == 1) {
697 *frame_flags |= FRAMEFLAGS_BWDREF;
698 } else {
699 *frame_flags &= ~FRAMEFLAGS_BWDREF;
700 }
701
702 if (cpi->common.current_frame.frame_type == KEY_FRAME) {
703 *frame_flags |= FRAMEFLAGS_KEY;
704 } else {
705 *frame_flags &= ~FRAMEFLAGS_KEY;
706 }
707}
708
709#define DUMP_REF_FRAME_IMAGES 0
710
711#if DUMP_REF_FRAME_IMAGES == 1
712static int dump_one_image(AV1_COMMON *cm,
713 const YV12_BUFFER_CONFIG *const ref_buf,
714 char *file_name) {
715 int h;
716 FILE *f_ref = NULL;
717
718 if (ref_buf == NULL) {
719 printf("Frame data buffer is NULL.\n");
720 return AOM_CODEC_MEM_ERROR;
721 }
722
723 if ((f_ref = fopen(file_name, "wb")) == NULL) {
724 printf("Unable to open file %s to write.\n", file_name);
725 return AOM_CODEC_MEM_ERROR;
726 }
727
728 // --- Y ---
729 for (h = 0; h < cm->height; ++h) {
730 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
731 }
732 // --- U ---
733 for (h = 0; h < (cm->height >> 1); ++h) {
734 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
735 f_ref);
736 }
737 // --- V ---
738 for (h = 0; h < (cm->height >> 1); ++h) {
739 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
740 f_ref);
741 }
742
743 fclose(f_ref);
744
745 return AOM_CODEC_OK;
746}
747
748static void dump_ref_frame_images(AV1_COMP *cpi) {
749 AV1_COMMON *const cm = &cpi->common;
750 MV_REFERENCE_FRAME ref_frame;
751
752 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
753 char file_name[256] = "";
754 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
755 cm->current_frame.frame_number, ref_frame);
756 dump_one_image(cm, get_ref_frame_yv12_buf(cpi, ref_frame), file_name);
757 }
758}
759#endif // DUMP_REF_FRAME_IMAGES == 1
760
Jingning Han81d6fbb2019-07-15 10:14:13 -0700761int av1_get_refresh_ref_frame_map(int refresh_frame_flags) {
Jingning Hanf58175c2019-07-07 15:02:00 -0700762 int ref_map_index = INVALID_IDX;
763
764 for (ref_map_index = 0; ref_map_index < REF_FRAMES; ++ref_map_index)
765 if ((refresh_frame_flags >> ref_map_index) & 1) break;
766
767 return ref_map_index;
768}
769
Jingning Han4711eb12019-08-01 09:56:59 -0700770static void update_arf_stack(int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700771 RefBufferStack *ref_buffer_stack) {
Jingning Han42266ca2019-07-12 14:37:16 -0700772 if (ref_buffer_stack->arf_stack_size >= 0) {
773 if (ref_buffer_stack->arf_stack[0] == ref_map_index)
774 stack_pop(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size);
Jingning Hanf58175c2019-07-07 15:02:00 -0700775 }
776
Jingning Han42266ca2019-07-12 14:37:16 -0700777 if (ref_buffer_stack->lst_stack_size) {
778 for (int i = ref_buffer_stack->lst_stack_size - 1; i >= 0; --i) {
779 if (ref_buffer_stack->lst_stack[i] == ref_map_index) {
780 for (int idx = i; idx < ref_buffer_stack->lst_stack_size - 1; ++idx)
781 ref_buffer_stack->lst_stack[idx] =
782 ref_buffer_stack->lst_stack[idx + 1];
783 ref_buffer_stack->lst_stack[i] = INVALID_IDX;
784 --ref_buffer_stack->lst_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700785 }
786 }
787 }
788
Jingning Han42266ca2019-07-12 14:37:16 -0700789 if (ref_buffer_stack->gld_stack_size) {
790 for (int i = ref_buffer_stack->gld_stack_size - 1; i >= 0; --i) {
791 if (ref_buffer_stack->gld_stack[i] == ref_map_index) {
792 for (int idx = i; idx < ref_buffer_stack->gld_stack_size - 1; ++idx)
793 ref_buffer_stack->gld_stack[idx] =
794 ref_buffer_stack->gld_stack[idx + 1];
795 ref_buffer_stack->gld_stack[i] = INVALID_IDX;
796 --ref_buffer_stack->gld_stack_size;
Jingning Hanf58175c2019-07-07 15:02:00 -0700797 }
798 }
799 }
800}
801
Jingning Han647f2d12019-07-23 14:15:42 -0700802// Update reference frame stack info.
Jingning Han42266ca2019-07-12 14:37:16 -0700803void av1_update_ref_frame_map(AV1_COMP *cpi,
804 FRAME_UPDATE_TYPE frame_update_type,
Jingning Han81d6fbb2019-07-15 10:14:13 -0700805 int ref_map_index,
Jingning Han42266ca2019-07-12 14:37:16 -0700806 RefBufferStack *ref_buffer_stack) {
David Turner73245762019-02-11 16:42:34 +0000807 AV1_COMMON *const cm = &cpi->common;
Jingning Han47aaf872019-07-21 14:56:32 -0700808 // TODO(jingning): Consider the S-frame same as key frame for the
809 // reference frame tracking purpose. The logic might be better
810 // expressed than converting the frame update type.
811 if (frame_is_sframe(cm)) frame_update_type = KEY_FRAME;
812
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700813 if (is_frame_droppable(cpi)) return;
814
Jingning Han81d6fbb2019-07-15 10:14:13 -0700815 switch (frame_update_type) {
816 case KEY_FRAME:
817 stack_reset(ref_buffer_stack->lst_stack,
818 &ref_buffer_stack->lst_stack_size);
819 stack_reset(ref_buffer_stack->gld_stack,
820 &ref_buffer_stack->gld_stack_size);
821 stack_reset(ref_buffer_stack->arf_stack,
822 &ref_buffer_stack->arf_stack_size);
823 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
824 ref_map_index);
825 break;
826 case GF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700827 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700828 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
829 ref_map_index);
830 break;
831 case LF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700832 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700833 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
834 ref_map_index);
835 break;
836 case ARF_UPDATE:
837 case INTNL_ARF_UPDATE:
Jingning Han4711eb12019-08-01 09:56:59 -0700838 update_arf_stack(ref_map_index, ref_buffer_stack);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700839 stack_push(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size,
840 ref_map_index);
841 break;
842 case OVERLAY_UPDATE:
Jingning Han5738e032019-07-22 15:22:52 -0700843 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
844 &ref_buffer_stack->arf_stack_size);
845 stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
846 ref_map_index);
Jingning Han81d6fbb2019-07-15 10:14:13 -0700847 break;
848 case INTNL_OVERLAY_UPDATE:
849 ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
850 &ref_buffer_stack->arf_stack_size);
851 stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
852 ref_map_index);
853 break;
854 default: assert(0 && "unknown type");
Jingning Hancf6d3252019-07-03 14:26:45 -0700855 }
856
Jingning Han84a70502019-07-19 11:38:14 -0700857 return;
David Turner73245762019-02-11 16:42:34 +0000858}
859
Jingning Han42266ca2019-07-12 14:37:16 -0700860static int get_free_ref_map_index(const RefBufferStack *ref_buffer_stack) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700861 for (int idx = 0; idx < REF_FRAMES; ++idx) {
862 int is_free = 1;
Jingning Han42266ca2019-07-12 14:37:16 -0700863 for (int i = 0; i < ref_buffer_stack->arf_stack_size; ++i) {
864 if (ref_buffer_stack->arf_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700865 is_free = 0;
866 break;
867 }
868 }
869
Jingning Han42266ca2019-07-12 14:37:16 -0700870 for (int i = 0; i < ref_buffer_stack->lst_stack_size; ++i) {
871 if (ref_buffer_stack->lst_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700872 is_free = 0;
873 break;
874 }
875 }
876
Jingning Han42266ca2019-07-12 14:37:16 -0700877 for (int i = 0; i < ref_buffer_stack->gld_stack_size; ++i) {
878 if (ref_buffer_stack->gld_stack[i] == idx) {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700879 is_free = 0;
880 break;
881 }
882 }
883
884 if (is_free) return idx;
885 }
886 return INVALID_IDX;
887}
888
Jingning Han42266ca2019-07-12 14:37:16 -0700889int av1_get_refresh_frame_flags(const AV1_COMP *const cpi,
890 const EncodeFrameParams *const frame_params,
891 FRAME_UPDATE_TYPE frame_update_type,
892 const RefBufferStack *const ref_buffer_stack) {
David Turner6e8b4d92019-02-18 15:01:33 +0000893 const AV1_COMMON *const cm = &cpi->common;
894
895 // Switch frames and shown key-frames overwrite all reference slots
896 if ((frame_params->frame_type == KEY_FRAME && frame_params->show_frame) ||
897 frame_params->frame_type == S_FRAME)
898 return 0xFF;
899
900 // show_existing_frames don't actually send refresh_frame_flags so set the
901 // flags to 0 to keep things consistent.
David Turnere86ee0d2019-02-18 17:16:28 +0000902 if (frame_params->show_existing_frame &&
903 (!frame_params->error_resilient_mode ||
904 frame_params->frame_type == KEY_FRAME)) {
David Turner6e8b4d92019-02-18 15:01:33 +0000905 return 0;
906 }
907
Jingning Hanbcbbd8c2019-07-21 16:37:12 -0700908 if (is_frame_droppable(cpi)) return 0;
909
David Turner6e8b4d92019-02-18 15:01:33 +0000910 int refresh_mask = 0;
911
David Turner6e8b4d92019-02-18 15:01:33 +0000912 if (cpi->ext_refresh_frame_flags_pending) {
913 // Unfortunately the encoder interface reflects the old refresh_*_frame
914 // flags so we have to replicate the old refresh_frame_flags logic here in
915 // order to preserve the behaviour of the flag overrides.
Jingning Han0a2af4e2019-07-08 19:30:03 -0700916 int ref_frame_map_idx = get_ref_frame_map_idx(cm, LAST3_FRAME);
917 if (ref_frame_map_idx != INVALID_IDX)
918 refresh_mask |= cpi->ext_refresh_last_frame << ref_frame_map_idx;
919
920 ref_frame_map_idx = get_ref_frame_map_idx(cm, EXTREF_FRAME);
921 if (ref_frame_map_idx != INVALID_IDX)
922 refresh_mask |= cpi->ext_refresh_bwd_ref_frame << ref_frame_map_idx;
923
924 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF2_FRAME);
925 if (ref_frame_map_idx != INVALID_IDX)
926 refresh_mask |= cpi->ext_refresh_alt2_ref_frame << ref_frame_map_idx;
927
David Turner6e8b4d92019-02-18 15:01:33 +0000928 if (frame_update_type == OVERLAY_UPDATE) {
Jingning Han5738e032019-07-22 15:22:52 -0700929 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
930 if (ref_frame_map_idx != INVALID_IDX)
931 refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000932 } else {
Jingning Han0a2af4e2019-07-08 19:30:03 -0700933 ref_frame_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
934 if (ref_frame_map_idx != INVALID_IDX)
935 refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
936
937 ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
938 if (ref_frame_map_idx != INVALID_IDX)
939 refresh_mask |= cpi->ext_refresh_alt_ref_frame << ref_frame_map_idx;
David Turner6e8b4d92019-02-18 15:01:33 +0000940 }
941 return refresh_mask;
942 }
943
Jingning Hanc9c172d2019-07-23 14:10:32 -0700944 // Search for the open slot to store the current frame.
Jingning Han81d6fbb2019-07-15 10:14:13 -0700945 int free_fb_index = get_free_ref_map_index(ref_buffer_stack);
Jingning Han0a2af4e2019-07-08 19:30:03 -0700946 switch (frame_update_type) {
947 case KF_UPDATE:
948 case GF_UPDATE:
949 if (free_fb_index != INVALID_IDX) {
950 refresh_mask = 1 << free_fb_index;
951 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700952 if (ref_buffer_stack->gld_stack_size)
953 refresh_mask =
954 1 << ref_buffer_stack
955 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700956 else
Jingning Han42266ca2019-07-12 14:37:16 -0700957 refresh_mask =
958 1 << ref_buffer_stack
959 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700960 }
961 break;
962 case LF_UPDATE:
963 if (free_fb_index != INVALID_IDX) {
964 refresh_mask = 1 << free_fb_index;
965 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700966 if (ref_buffer_stack->lst_stack_size >= 2)
967 refresh_mask =
968 1 << ref_buffer_stack
969 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700970 else
971 assert(0 && "No ref map index found");
972 }
973 break;
974 case ARF_UPDATE:
975 if (free_fb_index != INVALID_IDX) {
976 refresh_mask = 1 << free_fb_index;
977 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700978 if (ref_buffer_stack->gld_stack_size >= 3)
979 refresh_mask =
980 1 << ref_buffer_stack
981 ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
982 else if (ref_buffer_stack->lst_stack_size >= 2)
983 refresh_mask =
984 1 << ref_buffer_stack
985 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700986 else
987 assert(0 && "No ref map index found");
988 }
989 break;
990 case INTNL_ARF_UPDATE:
991 if (free_fb_index != INVALID_IDX) {
992 refresh_mask = 1 << free_fb_index;
993 } else {
Jingning Han42266ca2019-07-12 14:37:16 -0700994 refresh_mask =
995 1 << ref_buffer_stack
996 ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -0700997 }
998 break;
Jingning Han5738e032019-07-22 15:22:52 -0700999 case OVERLAY_UPDATE: break;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001000 case INTNL_OVERLAY_UPDATE: break;
1001 default: assert(0); break;
1002 }
1003
1004 return refresh_mask;
David Turner6e8b4d92019-02-18 15:01:33 +00001005}
1006
Cheng Chen7abe3132019-06-19 11:55:28 -07001007#if !CONFIG_REALTIME_ONLY
Cheng Chen5083a9f2019-07-12 15:33:34 -07001008void setup_mi(AV1_COMP *const cpi, YV12_BUFFER_CONFIG *src) {
1009 AV1_COMMON *const cm = &cpi->common;
1010 const int num_planes = av1_num_planes(cm);
1011 MACROBLOCK *const x = &cpi->td.mb;
1012 MACROBLOCKD *const xd = &x->e_mbd;
1013
1014 av1_setup_src_planes(x, src, 0, 0, num_planes, cm->seq_params.sb_size);
1015
1016 av1_setup_block_planes(xd, cm->seq_params.subsampling_x,
1017 cm->seq_params.subsampling_y, num_planes);
1018
1019 xd->mi = cm->mi_grid_base;
1020 xd->mi[0] = cm->mi;
1021 x->mbmi_ext = cpi->mbmi_ext_base;
1022}
1023
Cheng Chen7abe3132019-06-19 11:55:28 -07001024// Apply temporal filtering to key frames and encode the filtered frame.
1025// If the current frame is not key frame, this function is identical to
1026// av1_encode().
1027static int denoise_and_encode(AV1_COMP *const cpi, uint8_t *const dest,
1028 EncodeFrameInput *const frame_input,
1029 EncodeFrameParams *const frame_params,
1030 EncodeFrameResults *const frame_results,
1031 int *temporal_filtered) {
1032 if (frame_params->frame_type != KEY_FRAME) {
Cheng Chen7abe3132019-06-19 11:55:28 -07001033 if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
1034 AOM_CODEC_OK) {
1035 return AOM_CODEC_ERROR;
1036 }
1037 return AOM_CODEC_OK;
1038 }
1039
1040 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
1041 AV1_COMMON *const cm = &cpi->common;
1042 double noise_level;
1043 const int use_hbd = frame_input->source->flags & YV12_FLAG_HIGHBITDEPTH;
1044 if (use_hbd) {
1045 noise_level = highbd_estimate_noise(
1046 frame_input->source->y_buffer, frame_input->source->y_crop_width,
1047 frame_input->source->y_crop_height, frame_input->source->y_stride,
1048 cm->seq_params.bit_depth, EDGE_THRESHOLD);
1049 } else {
1050 noise_level = estimate_noise(frame_input->source->y_buffer,
1051 frame_input->source->y_crop_width,
1052 frame_input->source->y_crop_height,
1053 frame_input->source->y_stride, EDGE_THRESHOLD);
1054 }
1055 const int apply_filtering =
1056 oxcf->pass == 2 && frame_params->frame_type == KEY_FRAME &&
1057 cpi->rc.frames_to_key > NUM_KEY_FRAME_DENOISING && noise_level > 0 &&
1058 !is_lossless_requested(oxcf) && oxcf->arnr_max_frames > 0;
1059
1060 // Apply filtering to key frame and encode.
1061 if (apply_filtering) {
Cheng Chen5083a9f2019-07-12 15:33:34 -07001062 // Initialization for frame motion estimation.
1063 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
1064 av1_init_context_buffers(cm);
1065 setup_mi(cpi, frame_input->source);
1066 av1_init_macroblockd(cm, xd, NULL);
1067 memset(cpi->mbmi_ext_base, 0,
1068 cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));
1069
1070 av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
1071 av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
1072 av1_set_rd_speed_thresholds(cpi);
1073 av1_setup_frame_buf_refs(cm);
1074 av1_setup_frame_sign_bias(cm);
1075 av1_frame_init_quantizer(cpi);
1076 av1_setup_past_independence(cm);
1077
Cheng Chen7abe3132019-06-19 11:55:28 -07001078 // Keep a copy of the source image.
Cheng Chen5083a9f2019-07-12 15:33:34 -07001079 const int num_planes = av1_num_planes(cm);
Cheng Chen7abe3132019-06-19 11:55:28 -07001080 aom_yv12_copy_frame(frame_input->source, &cpi->source_kf_buffer,
1081 num_planes);
Cheng Chen7abe3132019-06-19 11:55:28 -07001082 av1_temporal_filter(cpi, -1);
1083 aom_extend_frame_borders(&cpi->alt_ref_buffer, num_planes);
Cheng Chen5083a9f2019-07-12 15:33:34 -07001084 // Use the filtered frame for encoding.
Cheng Chen7abe3132019-06-19 11:55:28 -07001085 frame_input->source = &cpi->alt_ref_buffer;
Cheng Chen5083a9f2019-07-12 15:33:34 -07001086 *temporal_filtered = 1;
Cheng Chen7abe3132019-06-19 11:55:28 -07001087 if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
1088 AOM_CODEC_OK) {
1089 return AOM_CODEC_ERROR;
1090 }
1091 // Set frame_input source to true source for psnr calculation.
1092 if (oxcf->arnr_max_frames > 0 && *temporal_filtered) {
1093 aom_yv12_copy_frame(&cpi->source_kf_buffer, cpi->source, num_planes);
1094 aom_yv12_copy_frame(&cpi->source_kf_buffer, cpi->unscaled_source,
1095 num_planes);
1096 }
1097 } else {
1098 // Encode other frames.
Cheng Chen7abe3132019-06-19 11:55:28 -07001099 if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
1100 AOM_CODEC_OK) {
1101 return AOM_CODEC_ERROR;
1102 }
1103 }
1104 return AOM_CODEC_OK;
1105}
1106#endif // !CONFIG_REALTIME_ONLY
1107
Jingning Handae645a2019-08-01 10:00:11 -07001108void av1_get_ref_frames(AV1_COMP *const cpi, RefBufferStack *ref_buffer_stack) {
Jingning Han0a2af4e2019-07-08 19:30:03 -07001109 AV1_COMMON *cm = &cpi->common;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001110
Jingning Han42266ca2019-07-12 14:37:16 -07001111 const int arf_stack_size = ref_buffer_stack->arf_stack_size;
1112 const int lst_stack_size = ref_buffer_stack->lst_stack_size;
1113 const int gld_stack_size = ref_buffer_stack->gld_stack_size;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001114
1115 // Initialization
1116 for (int i = 0; i < REF_FRAMES; ++i) cm->remapped_ref_idx[i] = INVALID_IDX;
1117
1118 if (arf_stack_size) {
1119 cm->remapped_ref_idx[ALTREF_FRAME - LAST_FRAME] =
Jingning Han42266ca2019-07-12 14:37:16 -07001120 ref_buffer_stack->arf_stack[arf_stack_size - 1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001121
1122 if (arf_stack_size > 1)
Jingning Han42266ca2019-07-12 14:37:16 -07001123 cm->remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] =
1124 ref_buffer_stack->arf_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001125
1126 if (arf_stack_size > 2)
Jingning Han42266ca2019-07-12 14:37:16 -07001127 cm->remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] =
1128 ref_buffer_stack->arf_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001129 }
1130
1131 if (lst_stack_size) {
Jingning Han42266ca2019-07-12 14:37:16 -07001132 cm->remapped_ref_idx[LAST_FRAME - LAST_FRAME] =
1133 ref_buffer_stack->lst_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001134
1135 if (lst_stack_size > 1)
Jingning Han42266ca2019-07-12 14:37:16 -07001136 cm->remapped_ref_idx[LAST2_FRAME - LAST_FRAME] =
1137 ref_buffer_stack->lst_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001138 }
1139
1140 if (gld_stack_size) {
1141 cm->remapped_ref_idx[GOLDEN_FRAME - LAST_FRAME] =
Jingning Hanba8052c2019-07-23 13:34:43 -07001142 ref_buffer_stack->gld_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001143
1144 if (gld_stack_size > 1) {
1145 if (arf_stack_size <= 1)
Jingning Han42266ca2019-07-12 14:37:16 -07001146 cm->remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] =
Jingning Hanba8052c2019-07-23 13:34:43 -07001147 ref_buffer_stack->gld_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001148 else
Jingning Han42266ca2019-07-12 14:37:16 -07001149 cm->remapped_ref_idx[LAST3_FRAME - LAST_FRAME] =
Jingning Hanba8052c2019-07-23 13:34:43 -07001150 ref_buffer_stack->gld_stack[1];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001151 }
1152 }
1153
1154 for (int idx = ALTREF_FRAME - LAST_FRAME; idx >= 0; --idx) {
1155 int ref_map_index = cm->remapped_ref_idx[idx];
1156
1157 if (ref_map_index != INVALID_IDX) continue;
1158
Jingning Han42266ca2019-07-12 14:37:16 -07001159 for (int i = 0;
1160 i < ref_buffer_stack->arf_stack_size && ref_map_index == INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001161 ++i) {
1162 int ref_idx = 0;
1163 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx)
Jingning Han42266ca2019-07-12 14:37:16 -07001164 if (ref_buffer_stack->arf_stack[i] == cm->remapped_ref_idx[ref_idx])
1165 break;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001166
1167 // not in use
1168 if (ref_idx > ALTREF_FRAME - LAST_FRAME) {
Jingning Han42266ca2019-07-12 14:37:16 -07001169 ref_map_index = ref_buffer_stack->arf_stack[i];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001170 break;
1171 }
1172 }
1173
Jingning Han42266ca2019-07-12 14:37:16 -07001174 for (int i = 0;
1175 i < ref_buffer_stack->gld_stack_size && ref_map_index == INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001176 ++i) {
1177 int ref_idx = 0;
1178 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx)
Jingning Han42266ca2019-07-12 14:37:16 -07001179 if (ref_buffer_stack->gld_stack[i] == cm->remapped_ref_idx[ref_idx])
1180 break;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001181
1182 // not in use
1183 if (ref_idx > ALTREF_FRAME - LAST_FRAME) {
Jingning Han42266ca2019-07-12 14:37:16 -07001184 ref_map_index = ref_buffer_stack->gld_stack[i];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001185 break;
1186 }
1187 }
1188
Jingning Han42266ca2019-07-12 14:37:16 -07001189 for (int i = 0;
1190 i < ref_buffer_stack->lst_stack_size && ref_map_index == INVALID_IDX;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001191 ++i) {
1192 int ref_idx = 0;
1193 for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx)
Jingning Han42266ca2019-07-12 14:37:16 -07001194 if (ref_buffer_stack->lst_stack[i] == cm->remapped_ref_idx[ref_idx])
1195 break;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001196
1197 // not in use
1198 if (ref_idx > ALTREF_FRAME - LAST_FRAME) {
Jingning Han42266ca2019-07-12 14:37:16 -07001199 ref_map_index = ref_buffer_stack->lst_stack[i];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001200 break;
1201 }
1202 }
1203
1204 if (ref_map_index != INVALID_IDX)
1205 cm->remapped_ref_idx[idx] = ref_map_index;
1206 else
Jingning Han42266ca2019-07-12 14:37:16 -07001207 cm->remapped_ref_idx[idx] = ref_buffer_stack->gld_stack[0];
Jingning Han0a2af4e2019-07-08 19:30:03 -07001208 }
Jingning Han42266ca2019-07-12 14:37:16 -07001209
1210 return;
Jingning Han0a2af4e2019-07-08 19:30:03 -07001211}
1212
David Turner056f7cd2019-01-07 17:48:13 +00001213int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
David Turner1539bb02019-01-24 15:28:13 +00001214 uint8_t *const dest, unsigned int *frame_flags,
David Turnerdedd8ff2019-01-23 13:59:46 +00001215 int64_t *const time_stamp, int64_t *const time_end,
Yue Chen1bc5be62018-08-24 13:57:32 -07001216 const aom_rational64_t *const timestamp_ratio,
1217 int flush) {
David Turner1539bb02019-01-24 15:28:13 +00001218 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
David Turner475a3132019-01-18 15:17:17 +00001219 AV1_COMMON *const cm = &cpi->common;
David Turner056f7cd2019-01-07 17:48:13 +00001220
David Turnerdedd8ff2019-01-23 13:59:46 +00001221 EncodeFrameInput frame_input;
David Turner04b70d82019-01-24 15:39:19 +00001222 EncodeFrameParams frame_params;
1223 EncodeFrameResults frame_results;
David Turnerdedd8ff2019-01-23 13:59:46 +00001224 memset(&frame_input, 0, sizeof(frame_input));
David Turner04b70d82019-01-24 15:39:19 +00001225 memset(&frame_params, 0, sizeof(frame_params));
1226 memset(&frame_results, 0, sizeof(frame_results));
1227
Sarah Parker97803fc2019-05-17 14:15:37 -07001228 // TODO(sarahparker) finish bit allocation for one pass pyramid
1229 if (oxcf->pass == 0 && oxcf->rc_mode != AOM_Q)
1230 cpi->oxcf.gf_max_pyr_height = USE_ALTREF_FOR_ONE_PASS;
1231
David Turnerb0c0aa32019-01-28 16:17:13 +00001232 if (oxcf->pass == 0 || oxcf->pass == 2) {
David Turnere86ee0d2019-02-18 17:16:28 +00001233 check_show_existing_frame(cpi, &frame_params);
1234 frame_params.show_existing_frame &= allow_show_existing(cpi, *frame_flags);
David Turnerb0c0aa32019-01-28 16:17:13 +00001235 } else {
David Turnere86ee0d2019-02-18 17:16:28 +00001236 frame_params.show_existing_frame = 0;
David Turnerb0c0aa32019-01-28 16:17:13 +00001237 }
1238
David Turnerdedd8ff2019-01-23 13:59:46 +00001239 int temporal_filtered = 0;
1240 struct lookahead_entry *source = NULL;
1241 struct lookahead_entry *last_source = NULL;
David Turner4f1f1812019-01-24 17:00:24 +00001242 FRAME_UPDATE_TYPE frame_update_type;
David Turnere86ee0d2019-02-18 17:16:28 +00001243 if (frame_params.show_existing_frame) {
David Turnerdedd8ff2019-01-23 13:59:46 +00001244 source = av1_lookahead_pop(cpi->lookahead, flush);
David Turner4f1f1812019-01-24 17:00:24 +00001245 frame_update_type = LF_UPDATE;
David Turnerdedd8ff2019-01-23 13:59:46 +00001246 } else {
1247 source = choose_frame_source(cpi, &temporal_filtered, &flush, &last_source,
David Turner4f1f1812019-01-24 17:00:24 +00001248 &frame_update_type, &frame_params);
1249 }
1250
Sarah Parker97803fc2019-05-17 14:15:37 -07001251 // In pass 0 and 2, we get the frame_update_type from gf_group
1252 if (oxcf->pass != 1) {
Urvang Joshi2e4aaf22019-05-08 11:38:00 -07001253 frame_update_type = get_frame_update_type(cpi);
David Turnerdedd8ff2019-01-23 13:59:46 +00001254 }
1255
1256 if (source == NULL) { // If no source was found, we can't encode a frame.
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001257#if !CONFIG_REALTIME_ONLY
David Turnerdedd8ff2019-01-23 13:59:46 +00001258 if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
1259 av1_end_first_pass(cpi); /* get last stats packet */
1260 cpi->twopass.first_pass_done = 1;
1261 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001262#endif
David Turnerdedd8ff2019-01-23 13:59:46 +00001263 return -1;
1264 }
1265
1266 frame_input.source = temporal_filtered ? &cpi->alt_ref_buffer : &source->img;
1267 frame_input.last_source = last_source != NULL ? &last_source->img : NULL;
1268 frame_input.ts_duration = source->ts_end - source->ts_start;
1269
1270 *time_stamp = source->ts_start;
1271 *time_end = source->ts_end;
1272 if (source->ts_start < cpi->first_time_stamp_ever) {
1273 cpi->first_time_stamp_ever = source->ts_start;
1274 cpi->last_end_time_stamp_seen = source->ts_start;
1275 }
1276
1277 av1_apply_encoding_flags(cpi, source->flags);
David Turnere86ee0d2019-02-18 17:16:28 +00001278 if (!frame_params.show_existing_frame)
David Turnerdedd8ff2019-01-23 13:59:46 +00001279 *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
David Turnerdedd8ff2019-01-23 13:59:46 +00001280
David Turnere86ee0d2019-02-18 17:16:28 +00001281 const int is_overlay = frame_params.show_existing_frame &&
1282 (frame_update_type == OVERLAY_UPDATE ||
1283 frame_update_type == INTNL_OVERLAY_UPDATE);
David Turner4f1f1812019-01-24 17:00:24 +00001284 if (frame_params.show_frame || is_overlay) {
David Turnerdedd8ff2019-01-23 13:59:46 +00001285 // Shown frames and arf-overlay frames need frame-rate considering
1286 adjust_frame_rate(cpi, source);
1287 }
1288
David Turnere86ee0d2019-02-18 17:16:28 +00001289 if (frame_params.show_existing_frame) {
David Turnerdedd8ff2019-01-23 13:59:46 +00001290 // show_existing_frame implies this frame is shown!
1291 frame_params.show_frame = 1;
1292 } else {
David Turnerdedd8ff2019-01-23 13:59:46 +00001293 if (cpi->film_grain_table) {
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001294 cm->cur_frame->film_grain_params_present = aom_film_grain_table_lookup(
David Turnerdedd8ff2019-01-23 13:59:46 +00001295 cpi->film_grain_table, *time_stamp, *time_end, 0 /* =erase */,
1296 &cm->film_grain_params);
Neil Birkbeckbd40ca72019-03-02 13:25:50 -08001297 } else {
1298 cm->cur_frame->film_grain_params_present =
1299 cm->seq_params.film_grain_params_present;
David Turnerdedd8ff2019-01-23 13:59:46 +00001300 }
David Turnerdedd8ff2019-01-23 13:59:46 +00001301 // only one operating point supported now
Yue Chen1bc5be62018-08-24 13:57:32 -07001302 const int64_t pts64 = ticks_to_timebase_units(timestamp_ratio, *time_stamp);
David Turnerdedd8ff2019-01-23 13:59:46 +00001303 if (pts64 < 0 || pts64 > UINT32_MAX) return AOM_CODEC_ERROR;
1304 cpi->common.frame_presentation_time = (uint32_t)pts64;
1305 }
1306
Marco Paniconicea99e22019-07-16 18:36:31 -07001307#if CONFIG_REALTIME_ONLY
1308 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
1309 frame_update_type = get_frame_update_type(cpi);
1310#else
1311 if (oxcf->pass == 0 && oxcf->mode == REALTIME && oxcf->lag_in_frames == 0) {
1312 av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
1313 frame_update_type = get_frame_update_type(cpi);
1314 } else if (oxcf->pass != 1 &&
1315 (!frame_params.show_existing_frame || is_overlay)) {
David Turner475a3132019-01-18 15:17:17 +00001316 // GF_GROUP needs updating for arf overlays as well as non-show-existing
David Turner73245762019-02-11 16:42:34 +00001317 av1_get_second_pass_params(cpi, &frame_params, *frame_flags);
Urvang Joshi2e4aaf22019-05-08 11:38:00 -07001318 frame_update_type = get_frame_update_type(cpi);
David Turner475a3132019-01-18 15:17:17 +00001319 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001320#endif
David Turner4f1f1812019-01-24 17:00:24 +00001321
David Turnere86ee0d2019-02-18 17:16:28 +00001322 if (frame_params.show_existing_frame &&
1323 frame_params.frame_type != KEY_FRAME) {
David Turner475a3132019-01-18 15:17:17 +00001324 // Force show-existing frames to be INTER, except forward keyframes
1325 frame_params.frame_type = INTER_FRAME;
1326 }
1327
David Turner056f7cd2019-01-07 17:48:13 +00001328 // TODO(david.turner@argondesign.com): Move all the encode strategy
1329 // (largely near av1_get_compressed_data) in here
1330
1331 // TODO(david.turner@argondesign.com): Change all the encode strategy to
1332 // modify frame_params instead of cm or cpi.
1333
David Turner04b70d82019-01-24 15:39:19 +00001334 // Per-frame encode speed. In theory this can vary, but things may have been
1335 // written assuming speed-level will not change within a sequence, so this
1336 // parameter should be used with caution.
1337 frame_params.speed = oxcf->speed;
1338
David Turnerddbff442019-01-21 14:58:42 +00001339 // Work out some encoding parameters specific to the pass:
Sarah Parker97803fc2019-05-17 14:15:37 -07001340 if (cpi->oxcf.pass == 0 && cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1341 av1_cyclic_refresh_update_parameters(cpi);
David Turnerddbff442019-01-21 14:58:42 +00001342 } else if (oxcf->pass == 1) {
1343 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&cpi->oxcf);
David Turner4f1f1812019-01-24 17:00:24 +00001344 const int kf_requested = (cm->current_frame.frame_number == 0 ||
David Turner73245762019-02-11 16:42:34 +00001345 (*frame_flags & FRAMEFLAGS_KEY));
David Turner4f1f1812019-01-24 17:00:24 +00001346 if (kf_requested && frame_update_type != OVERLAY_UPDATE &&
1347 frame_update_type != INTNL_OVERLAY_UPDATE) {
David Turnerddbff442019-01-21 14:58:42 +00001348 frame_params.frame_type = KEY_FRAME;
1349 } else {
1350 frame_params.frame_type = INTER_FRAME;
David Turnercb5e36f2019-01-17 17:15:25 +00001351 }
David Turnerddbff442019-01-21 14:58:42 +00001352 } else if (oxcf->pass == 2) {
1353#if CONFIG_MISMATCH_DEBUG
1354 mismatch_move_frame_idx_w();
1355#endif
1356#if TXCOEFF_COST_TIMER
1357 cm->txcoeff_cost_timer = 0;
1358 cm->txcoeff_cost_count = 0;
1359#endif
1360 }
1361
David Turner4f1f1812019-01-24 17:00:24 +00001362 if (oxcf->pass == 0 || oxcf->pass == 2) set_ext_overrides(cpi, &frame_params);
David Turnerddbff442019-01-21 14:58:42 +00001363
David Turner4f1f1812019-01-24 17:00:24 +00001364 // Shown keyframes and S frames refresh all reference buffers
1365 const int force_refresh_all =
1366 ((frame_params.frame_type == KEY_FRAME && frame_params.show_frame) ||
1367 frame_params.frame_type == S_FRAME) &&
David Turnere86ee0d2019-02-18 17:16:28 +00001368 !frame_params.show_existing_frame;
David Turner4f1f1812019-01-24 17:00:24 +00001369
David Turnerfe3aecb2019-02-06 14:42:42 +00001370 av1_configure_buffer_updates(cpi, &frame_params, frame_update_type,
1371 force_refresh_all);
David Turner4f1f1812019-01-24 17:00:24 +00001372
1373 if (oxcf->pass == 0 || oxcf->pass == 2) {
Marco Paniconi67142112019-07-24 15:00:31 -07001374 if (!cpi->ext_refresh_frame_flags_pending) {
Jingning Handae645a2019-08-01 10:00:11 -07001375 av1_get_ref_frames(cpi, &cpi->ref_buffer_stack);
Marco Paniconi67142112019-07-24 15:00:31 -07001376 } else if (cpi->svc.apply_external_ref_idx) {
1377 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++)
1378 cm->remapped_ref_idx[i] = cpi->svc.ref_idx[i];
1379 }
Jingning Han0a2af4e2019-07-08 19:30:03 -07001380
David Turnerddbff442019-01-21 14:58:42 +00001381 // Work out which reference frame slots may be used.
1382 frame_params.ref_frame_flags = get_ref_frame_flags(cpi);
David Turnerddbff442019-01-21 14:58:42 +00001383
David Turnera7f133c2019-01-22 14:47:16 +00001384 frame_params.primary_ref_frame =
1385 choose_primary_ref_frame(cpi, &frame_params);
Sarah Parkere1b22012019-06-06 16:35:25 -07001386 frame_params.order_offset = get_order_offset(&cpi->gf_group, &frame_params);
David Turner6e8b4d92019-02-18 15:01:33 +00001387
Jingning Han42266ca2019-07-12 14:37:16 -07001388 frame_params.refresh_frame_flags = av1_get_refresh_frame_flags(
1389 cpi, &frame_params, frame_update_type, &cpi->ref_buffer_stack);
David Turnera7f133c2019-01-22 14:47:16 +00001390 }
1391
David Turner73245762019-02-11 16:42:34 +00001392 // The way frame_params->remapped_ref_idx is setup is a placeholder.
David Turnerf4592292019-02-21 11:50:30 +00001393 // Currently, reference buffer assignment is done by update_ref_frame_map()
David Turner73245762019-02-11 16:42:34 +00001394 // which is called by high-level strategy AFTER encoding a frame. It modifies
1395 // cm->remapped_ref_idx. If you want to use an alternative method to
1396 // determine reference buffer assignment, just put your assignments into
1397 // frame_params->remapped_ref_idx here and they will be used when encoding
1398 // this frame. If frame_params->remapped_ref_idx is setup independently of
David Turnerf4592292019-02-21 11:50:30 +00001399 // cm->remapped_ref_idx then update_ref_frame_map() will have no effect.
David Turner73245762019-02-11 16:42:34 +00001400 memcpy(frame_params.remapped_ref_idx, cm->remapped_ref_idx,
1401 REF_FRAMES * sizeof(*cm->remapped_ref_idx));
1402
Ravi Chaudharyeeae7292019-06-26 13:32:59 +05301403 cpi->td.mb.e_mbd.delta_qindex = 0;
Yue Chen4e585cc2019-06-03 14:47:16 -07001404#if ENABLE_KF_TPL
Sarah Parker75ef4e32019-06-20 17:15:51 -07001405 if (oxcf->lag_in_frames > 0 && oxcf->pass != 1 &&
1406 frame_params.frame_type == KEY_FRAME && frame_params.show_frame) {
Yue Chen4e585cc2019-06-03 14:47:16 -07001407 av1_configure_buffer_updates(cpi, &frame_params, frame_update_type, 0);
1408 av1_set_frame_size(cpi, cm->width, cm->height);
Jingning Han81d6fbb2019-07-15 10:14:13 -07001409 av1_tpl_setup_stats(cpi, &frame_params, &frame_input);
Yue Chen4e585cc2019-06-03 14:47:16 -07001410 }
1411#endif // ENABLE_KF_TPL
1412
1413 if (!frame_params.show_existing_frame) {
1414 cm->using_qmatrix = cpi->oxcf.using_qm;
1415 cm->min_qmlevel = cpi->oxcf.qm_minlevel;
1416 cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
Sarah Parker75ef4e32019-06-20 17:15:51 -07001417 if (oxcf->lag_in_frames > 0 && oxcf->pass != 1) {
Sarah Parkere1b22012019-06-06 16:35:25 -07001418 if (cpi->gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
Yue Chen4e585cc2019-06-03 14:47:16 -07001419 av1_configure_buffer_updates(cpi, &frame_params, frame_update_type, 0);
1420 av1_set_frame_size(cpi, cm->width, cm->height);
Jingning Han81d6fbb2019-07-15 10:14:13 -07001421 av1_tpl_setup_stats(cpi, &frame_params, &frame_input);
Yue Chen4e585cc2019-06-03 14:47:16 -07001422 assert(cpi->num_gf_group_show_frames == 1);
1423 }
1424 }
1425 }
1426
Cheng Chen7abe3132019-06-19 11:55:28 -07001427#if TEMPORAL_FILTER_KEY_FRAME
1428 if (denoise_and_encode(cpi, dest, &frame_input, &frame_params, &frame_results,
1429 &temporal_filtered) != AOM_CODEC_OK) {
1430 return AOM_CODEC_ERROR;
1431 }
1432#else // !TEMPORAL_FILTER_KEY_FRAME
David Turnerdedd8ff2019-01-23 13:59:46 +00001433 if (av1_encode(cpi, dest, &frame_input, &frame_params, &frame_results) !=
David Turnerddbff442019-01-21 14:58:42 +00001434 AOM_CODEC_OK) {
1435 return AOM_CODEC_ERROR;
1436 }
Cheng Chen7abe3132019-06-19 11:55:28 -07001437#endif // TEMPORAL_FILTER_KEY_FRAME
Sarah Parker97803fc2019-05-17 14:15:37 -07001438 if (oxcf->pass != 1) cpi->num_gf_group_show_frames += frame_params.show_frame;
David Turnerddbff442019-01-21 14:58:42 +00001439
David Turner73245762019-02-11 16:42:34 +00001440 if (oxcf->pass == 0 || oxcf->pass == 2) {
1441 // First pass doesn't modify reference buffer assignment or produce frame
1442 // flags
1443 update_frame_flags(cpi, frame_flags);
Jingning Han81d6fbb2019-07-15 10:14:13 -07001444 int ref_map_index =
1445 av1_get_refresh_ref_frame_map(cm->current_frame.refresh_frame_flags);
1446 av1_update_ref_frame_map(cpi, frame_update_type, ref_map_index,
1447 &cpi->ref_buffer_stack);
David Turner73245762019-02-11 16:42:34 +00001448 }
1449
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001450#if !CONFIG_REALTIME_ONLY
Sarah Parker97803fc2019-05-17 14:15:37 -07001451 if (oxcf->pass != 1) {
David Turnerddbff442019-01-21 14:58:42 +00001452#if TXCOEFF_COST_TIMER
1453 cm->cum_txcoeff_cost_timer += cm->txcoeff_cost_timer;
1454 fprintf(stderr,
1455 "\ntxb coeff cost block number: %ld, frame time: %ld, cum time %ld "
1456 "in us\n",
1457 cm->txcoeff_cost_count, cm->txcoeff_cost_timer,
1458 cm->cum_txcoeff_cost_timer);
1459#endif
1460 av1_twopass_postencode_update(cpi);
1461 }
Jerome Jiang2612b4d2019-05-29 17:46:47 -07001462#endif // !CONFIG_REALTIME_ONLY
David Turnerddbff442019-01-21 14:58:42 +00001463
Sarah Parker97803fc2019-05-17 14:15:37 -07001464 if (oxcf->pass != 1) {
David Turnera7f133c2019-01-22 14:47:16 +00001465 update_fb_of_context_type(cpi, &frame_params, cpi->fb_of_context_type);
David Turner73245762019-02-11 16:42:34 +00001466 set_additional_frame_flags(cm, frame_flags);
David Turnerddbff442019-01-21 14:58:42 +00001467 update_rc_counts(cpi);
David Turner056f7cd2019-01-07 17:48:13 +00001468 }
1469
David Turner1539bb02019-01-24 15:28:13 +00001470 // Unpack frame_results:
David Turner056f7cd2019-01-07 17:48:13 +00001471 *size = frame_results.size;
1472
David Turner1539bb02019-01-24 15:28:13 +00001473 // Leave a signal for a higher level caller about if this frame is droppable
1474 if (*size > 0) {
1475 cpi->droppable = is_frame_droppable(cpi);
1476 }
1477
David Turner056f7cd2019-01-07 17:48:13 +00001478 return AOM_CODEC_OK;
1479}