• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
14 #include "config/aom_config.h"
15 #include "config/aom_scale_rtcd.h"
16 
17 #include "aom/aom_codec.h"
18 #include "aom/aom_encoder.h"
19 
20 #include "aom_ports/system_state.h"
21 
22 #if CONFIG_MISMATCH_DEBUG
23 #include "aom_util/debug_util.h"
24 #endif  // CONFIG_MISMATCH_DEBUG
25 
26 #include "av1/common/av1_common_int.h"
27 #include "av1/common/reconinter.h"
28 
29 #include "av1/encoder/encoder.h"
30 #include "av1/encoder/encode_strategy.h"
31 #include "av1/encoder/encodeframe.h"
32 #include "av1/encoder/firstpass.h"
33 #include "av1/encoder/pass2_strategy.h"
34 #include "av1/encoder/temporal_filter.h"
35 #include "av1/encoder/tpl_model.h"
36 
37 #define TEMPORAL_FILTER_KEY_FRAME (CONFIG_REALTIME_ONLY ? 0 : 1)
38 
av1_configure_buffer_updates(AV1_COMP * const cpi,EncodeFrameParams * const frame_params,const FRAME_UPDATE_TYPE type,int force_refresh_all)39 void av1_configure_buffer_updates(AV1_COMP *const cpi,
40                                   EncodeFrameParams *const frame_params,
41                                   const FRAME_UPDATE_TYPE type,
42                                   int force_refresh_all) {
43   // 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 
46   const ExternalFlags *const ext_flags = &cpi->ext_flags;
47   cpi->rc.is_src_frame_alt_ref = 0;
48 
49   switch (type) {
50     case KF_UPDATE:
51       frame_params->refresh_golden_frame = 1;
52       frame_params->refresh_bwd_ref_frame = 1;
53       frame_params->refresh_alt_ref_frame = 1;
54       break;
55 
56     case LF_UPDATE:
57       frame_params->refresh_golden_frame = 0;
58       frame_params->refresh_bwd_ref_frame = 0;
59       frame_params->refresh_alt_ref_frame = 0;
60       break;
61 
62     case GF_UPDATE:
63       frame_params->refresh_golden_frame = 1;
64       frame_params->refresh_bwd_ref_frame = 0;
65       frame_params->refresh_alt_ref_frame = 0;
66       break;
67 
68     case OVERLAY_UPDATE:
69       frame_params->refresh_golden_frame = 1;
70       frame_params->refresh_bwd_ref_frame = 0;
71       frame_params->refresh_alt_ref_frame = 0;
72 
73       cpi->rc.is_src_frame_alt_ref = 1;
74       break;
75 
76     case ARF_UPDATE:
77       frame_params->refresh_golden_frame = 0;
78       // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
79       frame_params->refresh_bwd_ref_frame = 0;
80       frame_params->refresh_alt_ref_frame = 1;
81       break;
82 
83     case INTNL_OVERLAY_UPDATE:
84       frame_params->refresh_golden_frame = 0;
85       frame_params->refresh_bwd_ref_frame = 0;
86       frame_params->refresh_alt_ref_frame = 0;
87 
88       cpi->rc.is_src_frame_alt_ref = 1;
89       break;
90 
91     case INTNL_ARF_UPDATE:
92       frame_params->refresh_golden_frame = 0;
93       frame_params->refresh_bwd_ref_frame = 1;
94       frame_params->refresh_alt_ref_frame = 0;
95       break;
96 
97     default: assert(0); break;
98   }
99 
100   if (ext_flags->refresh_frame_flags_pending &&
101       (!is_stat_generation_stage(cpi))) {
102     frame_params->refresh_golden_frame = ext_flags->refresh_golden_frame;
103     frame_params->refresh_alt_ref_frame = ext_flags->refresh_alt_ref_frame;
104     frame_params->refresh_bwd_ref_frame = ext_flags->refresh_bwd_ref_frame;
105   }
106 
107   if (force_refresh_all) {
108     frame_params->refresh_golden_frame = 1;
109     frame_params->refresh_bwd_ref_frame = 1;
110     frame_params->refresh_alt_ref_frame = 1;
111   }
112 }
113 
set_additional_frame_flags(const AV1_COMMON * const cm,unsigned int * const frame_flags)114 static void set_additional_frame_flags(const AV1_COMMON *const cm,
115                                        unsigned int *const frame_flags) {
116   if (frame_is_intra_only(cm)) {
117     *frame_flags |= FRAMEFLAGS_INTRAONLY;
118   }
119   if (frame_is_sframe(cm)) {
120     *frame_flags |= FRAMEFLAGS_SWITCH;
121   }
122   if (cm->features.error_resilient_mode) {
123     *frame_flags |= FRAMEFLAGS_ERROR_RESILIENT;
124   }
125 }
126 
update_keyframe_counters(AV1_COMP * cpi)127 static INLINE void update_keyframe_counters(AV1_COMP *cpi) {
128   if (cpi->common.show_frame) {
129     if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref ||
130         cpi->common.current_frame.frame_type == KEY_FRAME) {
131       // If this is a show_existing_frame with a source other than altref,
132       // or if it is not a displayed forward keyframe, the keyframe update
133       // counters were incremented when it was originally encoded.
134       cpi->rc.frames_since_key++;
135       cpi->rc.frames_to_key--;
136     }
137   }
138 }
139 
is_frame_droppable(const SVC * const svc,const ExternalFlags * const ext_flags)140 static INLINE int is_frame_droppable(const SVC *const svc,
141                                      const ExternalFlags *const ext_flags) {
142   // Droppable frame is only used by external refresh flags. VoD setting won't
143   // trigger its use case.
144   if (svc->external_ref_frame_config)
145     return svc->non_reference_frame;
146   else if (ext_flags->refresh_frame_flags_pending)
147     return !(ext_flags->refresh_alt_ref_frame ||
148              ext_flags->refresh_alt2_ref_frame ||
149              ext_flags->refresh_bwd_ref_frame ||
150              ext_flags->refresh_golden_frame || ext_flags->refresh_last_frame);
151   else
152     return 0;
153 }
154 
update_frames_till_gf_update(AV1_COMP * cpi)155 static INLINE void update_frames_till_gf_update(AV1_COMP *cpi) {
156   // TODO(weitinglin): Updating this counter for is_frame_droppable
157   // is a work-around to handle the condition when a frame is drop.
158   // We should fix the cpi->common.show_frame flag
159   // instead of checking the other condition to update the counter properly.
160   if (cpi->common.show_frame ||
161       is_frame_droppable(&cpi->svc, &cpi->ext_flags)) {
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 
update_gf_group_index(AV1_COMP * cpi)168 static INLINE void update_gf_group_index(AV1_COMP *cpi) {
169   // 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) {
175     ++cpi->gf_group.index;
176   }
177 }
178 
update_rc_counts(AV1_COMP * cpi)179 static void update_rc_counts(AV1_COMP *cpi) {
180   update_keyframe_counters(cpi);
181   update_frames_till_gf_update(cpi);
182   update_gf_group_index(cpi);
183 }
184 
set_ext_overrides(AV1_COMMON * const cm,EncodeFrameParams * const frame_params,ExternalFlags * const ext_flags)185 static void set_ext_overrides(AV1_COMMON *const cm,
186                               EncodeFrameParams *const frame_params,
187                               ExternalFlags *const ext_flags) {
188   // Overrides the defaults with the externally supplied values with
189   // av1_update_reference() and av1_update_entropy() calls
190   // Note: The overrides are valid only for the next frame passed
191   // to av1_encode_lowlevel()
192 
193   if (ext_flags->use_s_frame) {
194     frame_params->frame_type = S_FRAME;
195   }
196 
197   if (ext_flags->refresh_frame_context_pending) {
198     cm->features.refresh_frame_context = ext_flags->refresh_frame_context;
199     ext_flags->refresh_frame_context_pending = 0;
200   }
201   cm->features.allow_ref_frame_mvs = ext_flags->use_ref_frame_mvs;
202 
203   frame_params->error_resilient_mode = ext_flags->use_error_resilient;
204   // A keyframe is already error resilient and keyframes with
205   // error_resilient_mode interferes with the use of show_existing_frame
206   // when forward reference keyframes are enabled.
207   frame_params->error_resilient_mode &= frame_params->frame_type != KEY_FRAME;
208   // For bitstream conformance, s-frames must be error-resilient
209   frame_params->error_resilient_mode |= frame_params->frame_type == S_FRAME;
210 }
211 
get_current_frame_ref_type(const AV1_COMP * const cpi,const EncodeFrameParams * const frame_params)212 static int get_current_frame_ref_type(
213     const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
214   // We choose the reference "type" of this frame from the flags which indicate
215   // which reference frames will be refreshed by it.  More than one  of these
216   // flags may be set, so the order here implies an order of precedence. This is
217   // just used to choose the primary_ref_frame (as the most recent reference
218   // buffer of the same reference-type as the current frame)
219 
220   (void)frame_params;
221   // TODO(jingning): This table should be a lot simpler with the new
222   // ARF system in place. Keep frame_params for the time being as we are
223   // still evaluating a few design options.
224   switch (cpi->gf_group.layer_depth[cpi->gf_group.index]) {
225     case 0: return 0;
226     case 1: return 1;
227     case MAX_ARF_LAYERS:
228     case MAX_ARF_LAYERS + 1: return 4;
229     default: return 7;
230   }
231 }
232 
choose_primary_ref_frame(const AV1_COMP * const cpi,const EncodeFrameParams * const frame_params)233 static int choose_primary_ref_frame(
234     const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
235   const AV1_COMMON *const cm = &cpi->common;
236 
237   const int intra_only = frame_params->frame_type == KEY_FRAME ||
238                          frame_params->frame_type == INTRA_ONLY_FRAME;
239   if (intra_only || frame_params->error_resilient_mode || cpi->use_svc ||
240       cpi->ext_flags.use_primary_ref_none) {
241     return PRIMARY_REF_NONE;
242   }
243 
244   // In large scale case, always use Last frame's frame contexts.
245   // Note(yunqing): In other cases, primary_ref_frame is chosen based on
246   // cpi->gf_group.layer_depth[cpi->gf_group.index], which also controls
247   // frame bit allocation.
248   if (cm->tiles.large_scale) return (LAST_FRAME - LAST_FRAME);
249 
250   // Find the most recent reference frame with the same reference type as the
251   // current frame
252   const int current_ref_type = get_current_frame_ref_type(cpi, frame_params);
253   int wanted_fb = cpi->fb_of_context_type[current_ref_type];
254 
255   int primary_ref_frame = PRIMARY_REF_NONE;
256   for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
257     if (get_ref_frame_map_idx(cm, ref_frame) == wanted_fb) {
258       primary_ref_frame = ref_frame - LAST_FRAME;
259     }
260   }
261 
262   return primary_ref_frame;
263 }
264 
update_fb_of_context_type(const AV1_COMP * const cpi,const EncodeFrameParams * const frame_params,int * const fb_of_context_type)265 static void update_fb_of_context_type(
266     const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params,
267     int *const fb_of_context_type) {
268   const AV1_COMMON *const cm = &cpi->common;
269   const int current_frame_ref_type =
270       get_current_frame_ref_type(cpi, frame_params);
271 
272   if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
273       cpi->ext_flags.use_primary_ref_none) {
274     for (int i = 0; i < REF_FRAMES; i++) {
275       fb_of_context_type[i] = -1;
276     }
277     fb_of_context_type[current_frame_ref_type] =
278         cm->show_frame ? get_ref_frame_map_idx(cm, GOLDEN_FRAME)
279                        : get_ref_frame_map_idx(cm, ALTREF_FRAME);
280   }
281 
282   if (!encode_show_existing_frame(cm)) {
283     // Refresh fb_of_context_type[]: see encoder.h for explanation
284     if (cm->current_frame.frame_type == KEY_FRAME) {
285       // All ref frames are refreshed, pick one that will live long enough
286       fb_of_context_type[current_frame_ref_type] = 0;
287     } else {
288       // If more than one frame is refreshed, it doesn't matter which one we
289       // pick so pick the first.  LST sometimes doesn't refresh any: this is ok
290 
291       for (int i = 0; i < REF_FRAMES; i++) {
292         if (cm->current_frame.refresh_frame_flags & (1 << i)) {
293           fb_of_context_type[current_frame_ref_type] = i;
294           break;
295         }
296       }
297     }
298   }
299 }
300 
get_order_offset(const GF_GROUP * const gf_group,const EncodeFrameParams * const frame_params)301 static int get_order_offset(const GF_GROUP *const gf_group,
302                             const EncodeFrameParams *const frame_params) {
303   // shown frame by definition has order offset 0
304   // show_existing_frame ignores order_offset and simply takes the order_hint
305   // from the reference frame being shown.
306   if (frame_params->show_frame || frame_params->show_existing_frame) return 0;
307 
308   const int arf_offset =
309       AOMMIN((MAX_GF_INTERVAL - 1), gf_group->arf_src_offset[gf_group->index]);
310   return AOMMIN((MAX_GF_INTERVAL - 1), arf_offset);
311 }
312 
adjust_frame_rate(AV1_COMP * cpi,int64_t ts_start,int64_t ts_end)313 static void adjust_frame_rate(AV1_COMP *cpi, int64_t ts_start, int64_t ts_end) {
314   TimeStamps *time_stamps = &cpi->time_stamps;
315   int64_t this_duration;
316   int step = 0;
317 
318   // Clear down mmx registers
319   aom_clear_system_state();
320 
321   if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
322     cpi->framerate = cpi->svc.base_framerate;
323     av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
324     return;
325   }
326 
327   if (ts_start == time_stamps->first_ever) {
328     this_duration = ts_end - ts_start;
329     step = 1;
330   } else {
331     int64_t last_duration =
332         time_stamps->prev_end_seen - time_stamps->prev_start_seen;
333 
334     this_duration = ts_end - time_stamps->prev_end_seen;
335 
336     // do a step update if the duration changes by 10%
337     if (last_duration)
338       step = (int)((this_duration - last_duration) * 10 / last_duration);
339   }
340 
341   if (this_duration) {
342     if (step) {
343       av1_new_framerate(cpi, 10000000.0 / this_duration);
344     } else {
345       // Average this frame's rate into the last second's average
346       // frame rate. If we haven't seen 1 second yet, then average
347       // over the whole interval seen.
348       const double interval =
349           AOMMIN((double)(ts_end - time_stamps->first_ever), 10000000.0);
350       double avg_duration = 10000000.0 / cpi->framerate;
351       avg_duration *= (interval - avg_duration + this_duration);
352       avg_duration /= interval;
353 
354       av1_new_framerate(cpi, 10000000.0 / avg_duration);
355     }
356   }
357   time_stamps->prev_start_seen = ts_start;
358   time_stamps->prev_end_seen = ts_end;
359 }
360 
361 // If this is an alt-ref, returns the offset of the source frame used
362 // as the arf midpoint. Otherwise, returns 0.
get_arf_src_index(GF_GROUP * gf_group,int pass)363 static int get_arf_src_index(GF_GROUP *gf_group, int pass) {
364   int arf_src_index = 0;
365   if (pass != 1) arf_src_index = gf_group->arf_src_offset[gf_group->index];
366   return arf_src_index;
367 }
368 
369 // Called if this frame is an ARF or ARF2. Also handles forward-keyframes
370 // For an ARF set arf2=0, for ARF2 set arf2=1
371 // temporal_filtered is set to 1 if we temporally filter the ARF frame, so that
372 // the correct post-filter buffer can be used.
setup_arf_frame(AV1_COMP * const cpi,const int arf_src_index,int * code_arf,EncodeFrameParams * const frame_params,int * show_existing_alt_ref)373 static struct lookahead_entry *setup_arf_frame(
374     AV1_COMP *const cpi, const int arf_src_index, int *code_arf,
375     EncodeFrameParams *const frame_params, int *show_existing_alt_ref) {
376   AV1_COMMON *const cm = &cpi->common;
377   RATE_CONTROL *const rc = &cpi->rc;
378 #if !CONFIG_REALTIME_ONLY
379   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
380 #endif
381 
382   assert(arf_src_index <= rc->frames_to_key);
383   *code_arf = 0;
384 
385   struct lookahead_entry *source =
386       av1_lookahead_peek(cpi->lookahead, arf_src_index, cpi->compressor_stage);
387 
388   if (source != NULL) {
389     cm->showable_frame = 1;
390 
391     // When arf_src_index == rc->frames_to_key, it indicates a fwd_kf
392     if (arf_src_index == rc->frames_to_key) {
393       // Skip temporal filtering and mark as intra_only if we have a fwd_kf
394       cpi->no_show_kf = 1;
395     } else {
396 #if !CONFIG_REALTIME_ONLY
397       if (oxcf->arnr_max_frames > 0) {
398         // Produce the filtered ARF frame.
399         cm->current_frame.frame_type = INTER_FRAME;
400         FRAME_UPDATE_TYPE frame_update_type =
401             get_frame_update_type(&cpi->gf_group);
402         av1_configure_buffer_updates(cpi, frame_params, frame_update_type, 0);
403         *code_arf =
404             av1_temporal_filter(cpi, arf_src_index, show_existing_alt_ref);
405         if (*code_arf) {
406           aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
407         }
408       }
409 #else
410       (void)show_existing_alt_ref;
411 #endif
412     }
413     frame_params->show_frame = 0;
414   }
415   rc->source_alt_ref_pending = 0;
416   return source;
417 }
418 
419 // Determine whether there is a forced keyframe pending in the lookahead buffer
is_forced_keyframe_pending(struct lookahead_ctx * lookahead,const int up_to_index,const COMPRESSOR_STAGE compressor_stage)420 int is_forced_keyframe_pending(struct lookahead_ctx *lookahead,
421                                const int up_to_index,
422                                const COMPRESSOR_STAGE compressor_stage) {
423   for (int i = 0; i <= up_to_index; i++) {
424     const struct lookahead_entry *e =
425         av1_lookahead_peek(lookahead, i, compressor_stage);
426     if (e == NULL) {
427       // We have reached the end of the lookahead buffer and not early-returned
428       // so there isn't a forced key-frame pending.
429       return -1;
430     } else if (e->flags == AOM_EFLAG_FORCE_KF) {
431       return (i + 1);
432     } else {
433       continue;
434     }
435   }
436   return -1;  // Never reached
437 }
438 
439 // Check if we should encode an ARF or internal ARF.  If not, try a LAST
440 // Do some setup associated with the chosen source
441 // temporal_filtered, flush, and frame_update_type are outputs.
442 // Return the frame source, or NULL if we couldn't find one
choose_frame_source(AV1_COMP * const cpi,int * const code_arf,int * const flush,struct lookahead_entry ** last_source,EncodeFrameParams * const frame_params,int * show_existing_alt_ref)443 static struct lookahead_entry *choose_frame_source(
444     AV1_COMP *const cpi, int *const code_arf, int *const flush,
445     struct lookahead_entry **last_source, EncodeFrameParams *const frame_params,
446     int *show_existing_alt_ref) {
447   AV1_COMMON *const cm = &cpi->common;
448   struct lookahead_entry *source = NULL;
449   *code_arf = 0;
450 
451   // Should we encode an alt-ref frame.
452   int arf_src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
453   // TODO(Aasaipriya): Forced key frames need to be fixed when rc_mode != AOM_Q
454   if (arf_src_index &&
455       (is_forced_keyframe_pending(cpi->lookahead, arf_src_index,
456                                   cpi->compressor_stage) != -1) &&
457       cpi->oxcf.rc_mode != AOM_Q) {
458     arf_src_index = 0;
459     *flush = 1;
460   }
461 
462   if (arf_src_index)
463     source = setup_arf_frame(cpi, arf_src_index, code_arf, frame_params,
464                              show_existing_alt_ref);
465 
466   if (!source) {
467     // Get last frame source.
468     if (cm->current_frame.frame_number > 0) {
469       *last_source =
470           av1_lookahead_peek(cpi->lookahead, -1, cpi->compressor_stage);
471     }
472     // Read in the source frame.
473     source = av1_lookahead_pop(cpi->lookahead, *flush, cpi->compressor_stage);
474     if (source == NULL) return NULL;
475     frame_params->show_frame = 1;
476   }
477   return source;
478 }
479 
480 // Don't allow a show_existing_frame to coincide with an error resilient or
481 // S-Frame. An exception can be made in the case of a keyframe, since it does
482 // not depend on any previous frames.
allow_show_existing(const AV1_COMP * const cpi,unsigned int frame_flags)483 static int allow_show_existing(const AV1_COMP *const cpi,
484                                unsigned int frame_flags) {
485   if (cpi->common.current_frame.frame_number == 0) return 0;
486 
487   const struct lookahead_entry *lookahead_src =
488       av1_lookahead_peek(cpi->lookahead, 0, cpi->compressor_stage);
489   if (lookahead_src == NULL) return 1;
490 
491   const int is_error_resilient =
492       cpi->oxcf.error_resilient_mode ||
493       (lookahead_src->flags & AOM_EFLAG_ERROR_RESILIENT);
494   const int is_s_frame =
495       cpi->oxcf.s_frame_mode || (lookahead_src->flags & AOM_EFLAG_SET_S_FRAME);
496   const int is_key_frame =
497       (cpi->rc.frames_to_key == 0) || (frame_flags & FRAMEFLAGS_KEY);
498   return !(is_error_resilient || is_s_frame) || is_key_frame;
499 }
500 
501 // Update frame_flags to tell the encoder's caller what sort of frame was
502 // encoded.
update_frame_flags(AV1_COMP * cpi,unsigned int * frame_flags)503 static void update_frame_flags(AV1_COMP *cpi, unsigned int *frame_flags) {
504   if (encode_show_existing_frame(&cpi->common)) {
505     *frame_flags &= ~FRAMEFLAGS_GOLDEN;
506     *frame_flags &= ~FRAMEFLAGS_BWDREF;
507     *frame_flags &= ~FRAMEFLAGS_ALTREF;
508     *frame_flags &= ~FRAMEFLAGS_KEY;
509     return;
510   }
511 
512   if (cpi->refresh_golden_frame == 1) {
513     *frame_flags |= FRAMEFLAGS_GOLDEN;
514   } else {
515     *frame_flags &= ~FRAMEFLAGS_GOLDEN;
516   }
517 
518   if (cpi->refresh_alt_ref_frame == 1) {
519     *frame_flags |= FRAMEFLAGS_ALTREF;
520   } else {
521     *frame_flags &= ~FRAMEFLAGS_ALTREF;
522   }
523 
524   if (cpi->refresh_bwd_ref_frame == 1) {
525     *frame_flags |= FRAMEFLAGS_BWDREF;
526   } else {
527     *frame_flags &= ~FRAMEFLAGS_BWDREF;
528   }
529 
530   if (cpi->common.current_frame.frame_type == KEY_FRAME) {
531     *frame_flags |= FRAMEFLAGS_KEY;
532   } else {
533     *frame_flags &= ~FRAMEFLAGS_KEY;
534   }
535 }
536 
537 #define DUMP_REF_FRAME_IMAGES 0
538 
539 #if DUMP_REF_FRAME_IMAGES == 1
dump_one_image(AV1_COMMON * cm,const YV12_BUFFER_CONFIG * const ref_buf,char * file_name)540 static int dump_one_image(AV1_COMMON *cm,
541                           const YV12_BUFFER_CONFIG *const ref_buf,
542                           char *file_name) {
543   int h;
544   FILE *f_ref = NULL;
545 
546   if (ref_buf == NULL) {
547     printf("Frame data buffer is NULL.\n");
548     return AOM_CODEC_MEM_ERROR;
549   }
550 
551   if ((f_ref = fopen(file_name, "wb")) == NULL) {
552     printf("Unable to open file %s to write.\n", file_name);
553     return AOM_CODEC_MEM_ERROR;
554   }
555 
556   // --- Y ---
557   for (h = 0; h < cm->height; ++h) {
558     fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
559   }
560   // --- U ---
561   for (h = 0; h < (cm->height >> 1); ++h) {
562     fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
563            f_ref);
564   }
565   // --- V ---
566   for (h = 0; h < (cm->height >> 1); ++h) {
567     fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
568            f_ref);
569   }
570 
571   fclose(f_ref);
572 
573   return AOM_CODEC_OK;
574 }
575 
dump_ref_frame_images(AV1_COMP * cpi)576 static void dump_ref_frame_images(AV1_COMP *cpi) {
577   AV1_COMMON *const cm = &cpi->common;
578   MV_REFERENCE_FRAME ref_frame;
579 
580   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
581     char file_name[256] = "";
582     snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
583              cm->current_frame.frame_number, ref_frame);
584     dump_one_image(cm, get_ref_frame_yv12_buf(cpi, ref_frame), file_name);
585   }
586 }
587 #endif  // DUMP_REF_FRAME_IMAGES == 1
588 
av1_get_refresh_ref_frame_map(int refresh_frame_flags)589 int av1_get_refresh_ref_frame_map(int refresh_frame_flags) {
590   int ref_map_index = INVALID_IDX;
591 
592   for (ref_map_index = 0; ref_map_index < REF_FRAMES; ++ref_map_index)
593     if ((refresh_frame_flags >> ref_map_index) & 1) break;
594 
595   return ref_map_index;
596 }
597 
update_arf_stack(int ref_map_index,RefBufferStack * ref_buffer_stack)598 static void update_arf_stack(int ref_map_index,
599                              RefBufferStack *ref_buffer_stack) {
600   if (ref_buffer_stack->arf_stack_size >= 0) {
601     if (ref_buffer_stack->arf_stack[0] == ref_map_index)
602       stack_pop(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size);
603   }
604 
605   if (ref_buffer_stack->lst_stack_size) {
606     for (int i = ref_buffer_stack->lst_stack_size - 1; i >= 0; --i) {
607       if (ref_buffer_stack->lst_stack[i] == ref_map_index) {
608         for (int idx = i; idx < ref_buffer_stack->lst_stack_size - 1; ++idx)
609           ref_buffer_stack->lst_stack[idx] =
610               ref_buffer_stack->lst_stack[idx + 1];
611         ref_buffer_stack->lst_stack[ref_buffer_stack->lst_stack_size - 1] =
612             INVALID_IDX;
613         --ref_buffer_stack->lst_stack_size;
614       }
615     }
616   }
617 
618   if (ref_buffer_stack->gld_stack_size) {
619     for (int i = ref_buffer_stack->gld_stack_size - 1; i >= 0; --i) {
620       if (ref_buffer_stack->gld_stack[i] == ref_map_index) {
621         for (int idx = i; idx < ref_buffer_stack->gld_stack_size - 1; ++idx)
622           ref_buffer_stack->gld_stack[idx] =
623               ref_buffer_stack->gld_stack[idx + 1];
624         ref_buffer_stack->gld_stack[ref_buffer_stack->gld_stack_size - 1] =
625             INVALID_IDX;
626         --ref_buffer_stack->gld_stack_size;
627       }
628     }
629   }
630 }
631 
632 // Update reference frame stack info.
av1_update_ref_frame_map(AV1_COMP * cpi,FRAME_UPDATE_TYPE frame_update_type,int show_existing_frame,int ref_map_index,RefBufferStack * ref_buffer_stack)633 void av1_update_ref_frame_map(AV1_COMP *cpi,
634                               FRAME_UPDATE_TYPE frame_update_type,
635                               int show_existing_frame, int ref_map_index,
636                               RefBufferStack *ref_buffer_stack) {
637   AV1_COMMON *const cm = &cpi->common;
638   // TODO(jingning): Consider the S-frame same as key frame for the
639   // reference frame tracking purpose. The logic might be better
640   // expressed than converting the frame update type.
641   if (frame_is_sframe(cm)) frame_update_type = KEY_FRAME;
642 
643   if (is_frame_droppable(&cpi->svc, &cpi->ext_flags)) return;
644 
645   switch (frame_update_type) {
646     case KEY_FRAME:
647       if (show_existing_frame)
648         ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
649                                   &ref_buffer_stack->arf_stack_size);
650       stack_reset(ref_buffer_stack->lst_stack,
651                   &ref_buffer_stack->lst_stack_size);
652       stack_reset(ref_buffer_stack->gld_stack,
653                   &ref_buffer_stack->gld_stack_size);
654       stack_reset(ref_buffer_stack->arf_stack,
655                   &ref_buffer_stack->arf_stack_size);
656       stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
657                  ref_map_index);
658       break;
659     case GF_UPDATE:
660       update_arf_stack(ref_map_index, ref_buffer_stack);
661       stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
662                  ref_map_index);
663       // For nonrd_mode: update LAST as well on GF_UPDATE frame.
664       if (cpi->sf.rt_sf.use_nonrd_pick_mode)
665         stack_push(ref_buffer_stack->lst_stack,
666                    &ref_buffer_stack->lst_stack_size, ref_map_index);
667       break;
668     case LF_UPDATE:
669       update_arf_stack(ref_map_index, ref_buffer_stack);
670       stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
671                  ref_map_index);
672       break;
673     case ARF_UPDATE:
674     case INTNL_ARF_UPDATE:
675       update_arf_stack(ref_map_index, ref_buffer_stack);
676       stack_push(ref_buffer_stack->arf_stack, &ref_buffer_stack->arf_stack_size,
677                  ref_map_index);
678       break;
679     case OVERLAY_UPDATE:
680       ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
681                                 &ref_buffer_stack->arf_stack_size);
682       stack_push(ref_buffer_stack->gld_stack, &ref_buffer_stack->gld_stack_size,
683                  ref_map_index);
684       break;
685     case INTNL_OVERLAY_UPDATE:
686       ref_map_index = stack_pop(ref_buffer_stack->arf_stack,
687                                 &ref_buffer_stack->arf_stack_size);
688       stack_push(ref_buffer_stack->lst_stack, &ref_buffer_stack->lst_stack_size,
689                  ref_map_index);
690       break;
691     default: assert(0 && "unknown type");
692   }
693   return;
694 }
695 
get_free_ref_map_index(const RefBufferStack * ref_buffer_stack)696 static int get_free_ref_map_index(const RefBufferStack *ref_buffer_stack) {
697   for (int idx = 0; idx < REF_FRAMES; ++idx) {
698     int is_free = 1;
699     for (int i = 0; i < ref_buffer_stack->arf_stack_size; ++i) {
700       if (ref_buffer_stack->arf_stack[i] == idx) {
701         is_free = 0;
702         break;
703       }
704     }
705 
706     for (int i = 0; i < ref_buffer_stack->lst_stack_size; ++i) {
707       if (ref_buffer_stack->lst_stack[i] == idx) {
708         is_free = 0;
709         break;
710       }
711     }
712 
713     for (int i = 0; i < ref_buffer_stack->gld_stack_size; ++i) {
714       if (ref_buffer_stack->gld_stack[i] == idx) {
715         is_free = 0;
716         break;
717       }
718     }
719 
720     if (is_free) return idx;
721   }
722   return INVALID_IDX;
723 }
724 
av1_get_refresh_frame_flags(const AV1_COMP * const cpi,const EncodeFrameParams * const frame_params,FRAME_UPDATE_TYPE frame_update_type,const RefBufferStack * const ref_buffer_stack)725 int av1_get_refresh_frame_flags(const AV1_COMP *const cpi,
726                                 const EncodeFrameParams *const frame_params,
727                                 FRAME_UPDATE_TYPE frame_update_type,
728                                 const RefBufferStack *const ref_buffer_stack) {
729   const AV1_COMMON *const cm = &cpi->common;
730   const ExternalFlags *const ext_flags = &cpi->ext_flags;
731   const SVC *const svc = &cpi->svc;
732   // Switch frames and shown key-frames overwrite all reference slots
733   if ((frame_params->frame_type == KEY_FRAME && frame_params->show_frame) ||
734       frame_params->frame_type == S_FRAME)
735     return 0xFF;
736 
737   // show_existing_frames don't actually send refresh_frame_flags so set the
738   // flags to 0 to keep things consistent.
739   if (frame_params->show_existing_frame &&
740       (!frame_params->error_resilient_mode ||
741        frame_params->frame_type == KEY_FRAME)) {
742     return 0;
743   }
744 
745   if (is_frame_droppable(svc, ext_flags)) return 0;
746 
747   int refresh_mask = 0;
748 
749   if (ext_flags->refresh_frame_flags_pending) {
750     if (svc->external_ref_frame_config) {
751       for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
752         int ref_frame_map_idx = svc->ref_idx[i];
753         refresh_mask |= svc->refresh[ref_frame_map_idx] << ref_frame_map_idx;
754       }
755       return refresh_mask;
756     }
757     // Unfortunately the encoder interface reflects the old refresh_*_frame
758     // flags so we have to replicate the old refresh_frame_flags logic here in
759     // order to preserve the behaviour of the flag overrides.
760     int ref_frame_map_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
761     if (ref_frame_map_idx != INVALID_IDX)
762       refresh_mask |= ext_flags->refresh_last_frame << ref_frame_map_idx;
763 
764     ref_frame_map_idx = get_ref_frame_map_idx(cm, EXTREF_FRAME);
765     if (ref_frame_map_idx != INVALID_IDX)
766       refresh_mask |= ext_flags->refresh_bwd_ref_frame << ref_frame_map_idx;
767 
768     ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF2_FRAME);
769     if (ref_frame_map_idx != INVALID_IDX)
770       refresh_mask |= ext_flags->refresh_alt2_ref_frame << ref_frame_map_idx;
771 
772     if (frame_update_type == OVERLAY_UPDATE) {
773       ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
774       if (ref_frame_map_idx != INVALID_IDX)
775         refresh_mask |= ext_flags->refresh_golden_frame << ref_frame_map_idx;
776     } else {
777       ref_frame_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
778       if (ref_frame_map_idx != INVALID_IDX)
779         refresh_mask |= ext_flags->refresh_golden_frame << ref_frame_map_idx;
780 
781       ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
782       if (ref_frame_map_idx != INVALID_IDX)
783         refresh_mask |= ext_flags->refresh_alt_ref_frame << ref_frame_map_idx;
784     }
785     return refresh_mask;
786   }
787 
788   // Search for the open slot to store the current frame.
789   int free_fb_index = get_free_ref_map_index(ref_buffer_stack);
790   switch (frame_update_type) {
791     case KF_UPDATE:
792     case GF_UPDATE:
793       if (free_fb_index != INVALID_IDX) {
794         refresh_mask = 1 << free_fb_index;
795       } else {
796         if (ref_buffer_stack->gld_stack_size)
797           refresh_mask =
798               1 << ref_buffer_stack
799                        ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
800         else
801           refresh_mask =
802               1 << ref_buffer_stack
803                        ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
804       }
805       break;
806     case LF_UPDATE:
807       if (free_fb_index != INVALID_IDX) {
808         refresh_mask = 1 << free_fb_index;
809       } else {
810         if (ref_buffer_stack->lst_stack_size >= 2)
811           refresh_mask =
812               1 << ref_buffer_stack
813                        ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
814         else if (ref_buffer_stack->gld_stack_size >= 2)
815           refresh_mask =
816               1 << ref_buffer_stack
817                        ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
818         else
819           assert(0 && "No ref map index found");
820       }
821       break;
822     case ARF_UPDATE:
823       if (free_fb_index != INVALID_IDX) {
824         refresh_mask = 1 << free_fb_index;
825       } else {
826         if (ref_buffer_stack->gld_stack_size >= 3)
827           refresh_mask =
828               1 << ref_buffer_stack
829                        ->gld_stack[ref_buffer_stack->gld_stack_size - 1];
830         else if (ref_buffer_stack->lst_stack_size >= 2)
831           refresh_mask =
832               1 << ref_buffer_stack
833                        ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
834         else
835           assert(0 && "No ref map index found");
836       }
837       break;
838     case INTNL_ARF_UPDATE:
839       if (free_fb_index != INVALID_IDX) {
840         refresh_mask = 1 << free_fb_index;
841       } else {
842         refresh_mask =
843             1 << ref_buffer_stack
844                      ->lst_stack[ref_buffer_stack->lst_stack_size - 1];
845       }
846       break;
847     case OVERLAY_UPDATE: break;
848     case INTNL_OVERLAY_UPDATE: break;
849     default: assert(0); break;
850   }
851 
852   return refresh_mask;
853 }
854 
855 #if !CONFIG_REALTIME_ONLY
setup_mi(AV1_COMP * const cpi,YV12_BUFFER_CONFIG * src)856 void setup_mi(AV1_COMP *const cpi, YV12_BUFFER_CONFIG *src) {
857   AV1_COMMON *const cm = &cpi->common;
858   const int num_planes = av1_num_planes(cm);
859   MACROBLOCK *const x = &cpi->td.mb;
860   MACROBLOCKD *const xd = &x->e_mbd;
861 
862   av1_setup_src_planes(x, src, 0, 0, num_planes, cm->seq_params.sb_size);
863 
864   av1_setup_block_planes(xd, cm->seq_params.subsampling_x,
865                          cm->seq_params.subsampling_y, num_planes);
866 
867   set_mi_offsets(&cm->mi_params, xd, 0, 0);
868 }
869 
870 // Apply temporal filtering to key frames and encode the filtered frame.
871 // If the current frame is not key frame, this function is identical to
872 // av1_encode().
denoise_and_encode(AV1_COMP * const cpi,uint8_t * const dest,EncodeFrameInput * const frame_input,EncodeFrameParams * const frame_params,EncodeFrameResults * const frame_results)873 static int denoise_and_encode(AV1_COMP *const cpi, uint8_t *const dest,
874                               EncodeFrameInput *const frame_input,
875                               EncodeFrameParams *const frame_params,
876                               EncodeFrameResults *const frame_results) {
877   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
878   AV1_COMMON *const cm = &cpi->common;
879 
880   // Decide whether to apply temporal filtering to the source frame.
881   int apply_filtering =
882       frame_params->frame_type == KEY_FRAME &&
883       oxcf->enable_keyframe_filtering && !is_stat_generation_stage(cpi) &&
884       !frame_params->show_existing_frame &&
885       cpi->rc.frames_to_key > TF_NUM_FILTERING_FRAMES_FOR_KEY_FRAME &&
886       !is_lossless_requested(oxcf) && oxcf->arnr_max_frames > 0;
887   if (apply_filtering) {
888     const double y_noise_level = av1_estimate_noise_from_single_plane(
889         frame_input->source, 0, cm->seq_params.bit_depth);
890     apply_filtering = y_noise_level > 0;
891   }
892 
893   // Save the pointer to the original source image.
894   YV12_BUFFER_CONFIG *source_kf_buffer = frame_input->source;
895 
896   // Apply filtering to key frame.
897   if (apply_filtering) {
898     // Initialization for frame motion estimation.
899     MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
900     av1_init_mi_buffers(&cm->mi_params);
901     setup_mi(cpi, frame_input->source);
902     av1_init_macroblockd(cm, xd, NULL);
903     memset(
904         cpi->mbmi_ext_info.frame_base, 0,
905         cpi->mbmi_ext_info.alloc_size * sizeof(*cpi->mbmi_ext_info.frame_base));
906 
907     av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
908     av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
909     av1_set_rd_speed_thresholds(cpi);
910     av1_setup_frame_buf_refs(cm);
911     av1_setup_frame_sign_bias(cm);
912     av1_frame_init_quantizer(cpi);
913     av1_setup_past_independence(cm);
914 
915     if (!frame_params->show_frame) {
916       int arf_src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
917       av1_temporal_filter(cpi, -1 * arf_src_index, NULL);
918     } else {
919       av1_temporal_filter(cpi, -1, NULL);
920     }
921     aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
922     // Use the filtered frame for encoding.
923     frame_input->source = &cpi->alt_ref_buffer;
924     // Copy metadata info to alt-ref buffer.
925     aom_remove_metadata_from_frame_buffer(frame_input->source);
926     aom_copy_metadata_to_frame_buffer(frame_input->source,
927                                       source_kf_buffer->metadata);
928 
929     if (oxcf->enable_tpl_model && oxcf->lag_in_frames > 0 &&
930         frame_params->show_frame) {
931       av1_tpl_setup_stats(cpi, 0, frame_params, frame_input);
932     }
933   }
934 
935   if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
936       AOM_CODEC_OK) {
937     return AOM_CODEC_ERROR;
938   }
939 
940   // Set frame_input source to true source for psnr calculation.
941   if (apply_filtering) {
942     cpi->source = source_kf_buffer;
943     cpi->unscaled_source = source_kf_buffer;
944   }
945 
946   return AOM_CODEC_OK;
947 }
948 #endif  // !CONFIG_REALTIME_ONLY
949 
find_unused_ref_frame(const int * used_ref_frames,const int * stack,int stack_size)950 static INLINE int find_unused_ref_frame(const int *used_ref_frames,
951                                         const int *stack, int stack_size) {
952   for (int i = 0; i < stack_size; ++i) {
953     const int this_ref = stack[i];
954     int ref_idx = 0;
955     for (ref_idx = 0; ref_idx <= ALTREF_FRAME - LAST_FRAME; ++ref_idx) {
956       if (this_ref == used_ref_frames[ref_idx]) break;
957     }
958 
959     // not in use
960     if (ref_idx > ALTREF_FRAME - LAST_FRAME) return this_ref;
961   }
962 
963   return INVALID_IDX;
964 }
965 
av1_get_ref_frames(AV1_COMP * const cpi,RefBufferStack * ref_buffer_stack)966 void av1_get_ref_frames(AV1_COMP *const cpi, RefBufferStack *ref_buffer_stack) {
967   AV1_COMMON *cm = &cpi->common;
968   int *const remapped_ref_idx = cm->remapped_ref_idx;
969   int *const arf_stack = ref_buffer_stack->arf_stack;
970   int *const lst_stack = ref_buffer_stack->lst_stack;
971   int *const gld_stack = ref_buffer_stack->gld_stack;
972   const int arf_stack_size = ref_buffer_stack->arf_stack_size;
973   const int lst_stack_size = ref_buffer_stack->lst_stack_size;
974   const int gld_stack_size = ref_buffer_stack->gld_stack_size;
975 
976   // Initialization
977   for (int i = 0; i < REF_FRAMES; ++i) remapped_ref_idx[i] = INVALID_IDX;
978 
979   if (arf_stack_size) {
980     remapped_ref_idx[ALTREF_FRAME - LAST_FRAME] = arf_stack[arf_stack_size - 1];
981 
982     if (arf_stack_size > 1)
983       remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = arf_stack[0];
984 
985     if (arf_stack_size > 2)
986       remapped_ref_idx[ALTREF2_FRAME - LAST_FRAME] = arf_stack[1];
987   }
988 
989   if (lst_stack_size) {
990     remapped_ref_idx[LAST_FRAME - LAST_FRAME] = lst_stack[0];
991 
992     if (lst_stack_size > 1)
993       remapped_ref_idx[LAST2_FRAME - LAST_FRAME] = lst_stack[1];
994   }
995 
996   if (gld_stack_size) {
997     remapped_ref_idx[GOLDEN_FRAME - LAST_FRAME] = gld_stack[0];
998 
999     if (gld_stack_size > 1) {
1000       if (arf_stack_size <= 1)
1001         remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = gld_stack[1];
1002       else
1003         remapped_ref_idx[LAST3_FRAME - LAST_FRAME] = gld_stack[1];
1004     }
1005   }
1006 
1007   for (int idx = ALTREF_FRAME - LAST_FRAME; idx >= 0; --idx) {
1008     int ref_map_index = remapped_ref_idx[idx];
1009 
1010     if (ref_map_index != INVALID_IDX) continue;
1011 
1012     ref_map_index =
1013         find_unused_ref_frame(remapped_ref_idx, arf_stack, arf_stack_size);
1014 
1015     if (ref_map_index == INVALID_IDX) {
1016       ref_map_index =
1017           find_unused_ref_frame(remapped_ref_idx, gld_stack, gld_stack_size);
1018     }
1019 
1020     if (ref_map_index == INVALID_IDX) {
1021       ref_map_index =
1022           find_unused_ref_frame(remapped_ref_idx, lst_stack, lst_stack_size);
1023     }
1024 
1025     if (ref_map_index != INVALID_IDX)
1026       remapped_ref_idx[idx] = ref_map_index;
1027     else
1028       remapped_ref_idx[idx] = ref_buffer_stack->gld_stack[0];
1029   }
1030 }
1031 
av1_encode_strategy(AV1_COMP * const cpi,size_t * const size,uint8_t * const dest,unsigned int * frame_flags,int64_t * const time_stamp,int64_t * const time_end,const aom_rational64_t * const timestamp_ratio,int flush)1032 int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
1033                         uint8_t *const dest, unsigned int *frame_flags,
1034                         int64_t *const time_stamp, int64_t *const time_end,
1035                         const aom_rational64_t *const timestamp_ratio,
1036                         int flush) {
1037   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
1038   AV1_COMMON *const cm = &cpi->common;
1039   GF_GROUP *gf_group = &cpi->gf_group;
1040   ExternalFlags *const ext_flags = &cpi->ext_flags;
1041 
1042   EncodeFrameInput frame_input;
1043   EncodeFrameParams frame_params;
1044   EncodeFrameResults frame_results;
1045   memset(&frame_input, 0, sizeof(frame_input));
1046   memset(&frame_params, 0, sizeof(frame_params));
1047   memset(&frame_results, 0, sizeof(frame_results));
1048 
1049   // TODO(sarahparker) finish bit allocation for one pass pyramid
1050   if (has_no_stats_stage(cpi) && oxcf->rc_mode != AOM_Q) {
1051     cpi->oxcf.gf_max_pyr_height =
1052         AOMMIN(cpi->oxcf.gf_max_pyr_height, USE_ALTREF_FOR_ONE_PASS);
1053     cpi->oxcf.gf_min_pyr_height =
1054         AOMMIN(cpi->oxcf.gf_min_pyr_height, cpi->oxcf.gf_max_pyr_height);
1055   }
1056 
1057   if (!is_stat_generation_stage(cpi)) {
1058     // If this is a forward keyframe, mark as a show_existing_frame
1059     if (cpi->oxcf.fwd_kf_enabled && (gf_group->index == gf_group->size) &&
1060         gf_group->update_type[1] == ARF_UPDATE && cpi->rc.frames_to_key == 0) {
1061       frame_params.show_existing_frame = 1;
1062     } else {
1063       frame_params.show_existing_frame =
1064           ((oxcf->enable_overlay == 0 || cpi->sf.hl_sf.disable_overlay_frames ||
1065             cpi->show_existing_alt_ref) &&
1066            gf_group->update_type[gf_group->index] == OVERLAY_UPDATE) ||
1067           gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE;
1068     }
1069     frame_params.show_existing_frame &= allow_show_existing(cpi, *frame_flags);
1070 
1071     // Reset show_existing_alt_ref decision to 0 after it is used.
1072     if (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE) {
1073       cpi->show_existing_alt_ref = 0;
1074     }
1075   } else {
1076     frame_params.show_existing_frame = 0;
1077   }
1078 
1079   int code_arf = 0;
1080   struct lookahead_entry *source = NULL;
1081   struct lookahead_entry *last_source = NULL;
1082   if (frame_params.show_existing_frame) {
1083     source = av1_lookahead_pop(cpi->lookahead, flush, cpi->compressor_stage);
1084     frame_params.show_frame = 1;
1085   } else {
1086     int show_existing_alt_ref = 0;
1087     source = choose_frame_source(cpi, &code_arf, &flush, &last_source,
1088                                  &frame_params, &show_existing_alt_ref);
1089     if (gf_group->update_type[gf_group->index] == ARF_UPDATE)
1090       cpi->show_existing_alt_ref = show_existing_alt_ref;
1091   }
1092 
1093   if (source == NULL) {  // If no source was found, we can't encode a frame.
1094 #if !CONFIG_REALTIME_ONLY
1095     if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
1096       av1_end_first_pass(cpi); /* get last stats packet */
1097       cpi->twopass.first_pass_done = 1;
1098     }
1099 #endif
1100     return -1;
1101   }
1102 
1103   frame_input.source = code_arf ? &cpi->alt_ref_buffer : &source->img;
1104   frame_input.last_source = last_source != NULL ? &last_source->img : NULL;
1105   frame_input.ts_duration = source->ts_end - source->ts_start;
1106   // Save unfiltered source. It is used in av1_get_second_pass_params().
1107   cpi->unfiltered_source = frame_input.source;
1108 
1109   *time_stamp = source->ts_start;
1110   *time_end = source->ts_end;
1111   if (source->ts_start < cpi->time_stamps.first_ever) {
1112     cpi->time_stamps.first_ever = source->ts_start;
1113     cpi->time_stamps.prev_end_seen = source->ts_start;
1114   }
1115 
1116   av1_apply_encoding_flags(cpi, source->flags);
1117   if (!frame_params.show_existing_frame)
1118     *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
1119 
1120   // Shown frames and arf-overlay frames need frame-rate considering
1121   if (frame_params.show_frame)
1122     adjust_frame_rate(cpi, source->ts_start, source->ts_end);
1123 
1124   if (!frame_params.show_existing_frame) {
1125     if (cpi->film_grain_table) {
1126       cm->cur_frame->film_grain_params_present = aom_film_grain_table_lookup(
1127           cpi->film_grain_table, *time_stamp, *time_end, 0 /* =erase */,
1128           &cm->film_grain_params);
1129     } else {
1130       cm->cur_frame->film_grain_params_present =
1131           cm->seq_params.film_grain_params_present;
1132     }
1133     // only one operating point supported now
1134     const int64_t pts64 = ticks_to_timebase_units(timestamp_ratio, *time_stamp);
1135     if (pts64 < 0 || pts64 > UINT32_MAX) return AOM_CODEC_ERROR;
1136     cm->frame_presentation_time = (uint32_t)pts64;
1137   }
1138 
1139 #if CONFIG_REALTIME_ONLY
1140   av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
1141 #else
1142   if (has_no_stats_stage(cpi) && oxcf->mode == REALTIME &&
1143       oxcf->lag_in_frames == 0)
1144     av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
1145   else if (!is_stat_generation_stage(cpi))
1146     av1_get_second_pass_params(cpi, &frame_params, &frame_input, *frame_flags);
1147 #endif
1148   FRAME_UPDATE_TYPE frame_update_type = get_frame_update_type(gf_group);
1149 
1150   if (frame_params.show_existing_frame &&
1151       frame_params.frame_type != KEY_FRAME) {
1152     // Force show-existing frames to be INTER, except forward keyframes
1153     frame_params.frame_type = INTER_FRAME;
1154   }
1155 
1156   // TODO(david.turner@argondesign.com): Move all the encode strategy
1157   // (largely near av1_get_compressed_data) in here
1158 
1159   // TODO(david.turner@argondesign.com): Change all the encode strategy to
1160   // modify frame_params instead of cm or cpi.
1161 
1162   // Per-frame encode speed.  In theory this can vary, but things may have been
1163   // written assuming speed-level will not change within a sequence, so this
1164   // parameter should be used with caution.
1165   frame_params.speed = oxcf->speed;
1166 
1167   // Work out some encoding parameters specific to the pass:
1168   if (has_no_stats_stage(cpi) && cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1169     av1_cyclic_refresh_update_parameters(cpi);
1170   } else if (is_stat_generation_stage(cpi)) {
1171     cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&cpi->oxcf);
1172     const int kf_requested = (cm->current_frame.frame_number == 0 ||
1173                               (*frame_flags & FRAMEFLAGS_KEY));
1174     if (kf_requested && frame_update_type != OVERLAY_UPDATE &&
1175         frame_update_type != INTNL_OVERLAY_UPDATE) {
1176       frame_params.frame_type = KEY_FRAME;
1177     } else {
1178       frame_params.frame_type = INTER_FRAME;
1179     }
1180   } else if (is_stat_consumption_stage(cpi)) {
1181 #if CONFIG_MISMATCH_DEBUG
1182     mismatch_move_frame_idx_w();
1183 #endif
1184 #if TXCOEFF_COST_TIMER
1185     cm->txcoeff_cost_timer = 0;
1186     cm->txcoeff_cost_count = 0;
1187 #endif
1188   }
1189 
1190   if (!is_stat_generation_stage(cpi))
1191     set_ext_overrides(cm, &frame_params, ext_flags);
1192 
1193   // Shown keyframes and S frames refresh all reference buffers
1194   const int force_refresh_all =
1195       ((frame_params.frame_type == KEY_FRAME && frame_params.show_frame) ||
1196        frame_params.frame_type == S_FRAME) &&
1197       !frame_params.show_existing_frame;
1198 
1199   av1_configure_buffer_updates(cpi, &frame_params, frame_update_type,
1200                                force_refresh_all);
1201 
1202   if (!is_stat_generation_stage(cpi)) {
1203     const RefCntBuffer *ref_frames[INTER_REFS_PER_FRAME];
1204     const YV12_BUFFER_CONFIG *ref_frame_buf[INTER_REFS_PER_FRAME];
1205 
1206     if (!ext_flags->refresh_frame_flags_pending) {
1207       av1_get_ref_frames(cpi, &cpi->ref_buffer_stack);
1208     } else if (cpi->svc.external_ref_frame_config) {
1209       for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++)
1210         cm->remapped_ref_idx[i] = cpi->svc.ref_idx[i];
1211     }
1212 
1213     // Get the reference frames
1214     for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
1215       ref_frames[i] = get_ref_frame_buf(cm, ref_frame_priority_order[i]);
1216       ref_frame_buf[i] = ref_frames[i] != NULL ? &ref_frames[i]->buf : NULL;
1217     }
1218     // Work out which reference frame slots may be used.
1219     frame_params.ref_frame_flags = get_ref_frame_flags(
1220         &cpi->sf, ref_frame_buf, ext_flags->ref_frame_flags);
1221 
1222     frame_params.primary_ref_frame =
1223         choose_primary_ref_frame(cpi, &frame_params);
1224     frame_params.order_offset = get_order_offset(&cpi->gf_group, &frame_params);
1225 
1226     frame_params.refresh_frame_flags = av1_get_refresh_frame_flags(
1227         cpi, &frame_params, frame_update_type, &cpi->ref_buffer_stack);
1228 
1229     frame_params.existing_fb_idx_to_show =
1230         frame_params.show_existing_frame
1231             ? (frame_update_type == INTNL_OVERLAY_UPDATE
1232                    ? get_ref_frame_map_idx(cm, BWDREF_FRAME)
1233                    : get_ref_frame_map_idx(cm, ALTREF_FRAME))
1234             : INVALID_IDX;
1235   }
1236 
1237   // The way frame_params->remapped_ref_idx is setup is a placeholder.
1238   // Currently, reference buffer assignment is done by update_ref_frame_map()
1239   // which is called by high-level strategy AFTER encoding a frame.  It modifies
1240   // cm->remapped_ref_idx.  If you want to use an alternative method to
1241   // determine reference buffer assignment, just put your assignments into
1242   // frame_params->remapped_ref_idx here and they will be used when encoding
1243   // this frame.  If frame_params->remapped_ref_idx is setup independently of
1244   // cm->remapped_ref_idx then update_ref_frame_map() will have no effect.
1245   memcpy(frame_params.remapped_ref_idx, cm->remapped_ref_idx,
1246          REF_FRAMES * sizeof(*cm->remapped_ref_idx));
1247 
1248   cpi->td.mb.e_mbd.delta_qindex = 0;
1249 
1250   if (!frame_params.show_existing_frame) {
1251     cm->quant_params.using_qmatrix = cpi->oxcf.using_qm;
1252 #if !CONFIG_REALTIME_ONLY
1253     if (oxcf->lag_in_frames > 0 && !is_stat_generation_stage(cpi)) {
1254       if (cpi->gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
1255         av1_configure_buffer_updates(cpi, &frame_params, frame_update_type, 0);
1256         av1_set_frame_size(cpi, cm->width, cm->height);
1257         av1_tpl_setup_stats(cpi, 0, &frame_params, &frame_input);
1258         assert(cpi->num_gf_group_show_frames == 1);
1259       }
1260     }
1261 #endif
1262   }
1263 
1264 #if CONFIG_REALTIME_ONLY
1265   if (av1_encode(cpi, dest, &frame_input, &frame_params, &frame_results) !=
1266       AOM_CODEC_OK) {
1267     return AOM_CODEC_ERROR;
1268   }
1269 #else
1270   if (denoise_and_encode(cpi, dest, &frame_input, &frame_params,
1271                          &frame_results) != AOM_CODEC_OK) {
1272     return AOM_CODEC_ERROR;
1273   }
1274 #endif  // CONFIG_REALTIME_ONLY
1275   if (!is_stat_generation_stage(cpi))
1276     cpi->num_gf_group_show_frames += frame_params.show_frame;
1277 
1278   if (!is_stat_generation_stage(cpi)) {
1279     // First pass doesn't modify reference buffer assignment or produce frame
1280     // flags
1281     update_frame_flags(cpi, frame_flags);
1282     if (!ext_flags->refresh_frame_flags_pending) {
1283       int ref_map_index =
1284           av1_get_refresh_ref_frame_map(cm->current_frame.refresh_frame_flags);
1285       av1_update_ref_frame_map(cpi, frame_update_type, cm->show_existing_frame,
1286                                ref_map_index, &cpi->ref_buffer_stack);
1287     }
1288   }
1289 
1290 #if !CONFIG_REALTIME_ONLY
1291   if (!is_stat_generation_stage(cpi)) {
1292 #if TXCOEFF_COST_TIMER
1293     cm->cum_txcoeff_cost_timer += cm->txcoeff_cost_timer;
1294     fprintf(stderr,
1295             "\ntxb coeff cost block number: %ld, frame time: %ld, cum time %ld "
1296             "in us\n",
1297             cm->txcoeff_cost_count, cm->txcoeff_cost_timer,
1298             cm->cum_txcoeff_cost_timer);
1299 #endif
1300     av1_twopass_postencode_update(cpi);
1301   }
1302 #endif  // !CONFIG_REALTIME_ONLY
1303 
1304   if (!is_stat_generation_stage(cpi)) {
1305     update_fb_of_context_type(cpi, &frame_params, cpi->fb_of_context_type);
1306     set_additional_frame_flags(cm, frame_flags);
1307     update_rc_counts(cpi);
1308   }
1309 
1310   // Unpack frame_results:
1311   *size = frame_results.size;
1312 
1313   // Leave a signal for a higher level caller about if this frame is droppable
1314   if (*size > 0) {
1315     cpi->droppable = is_frame_droppable(&cpi->svc, ext_flags);
1316   }
1317 
1318   if (cpi->use_svc) av1_save_layer_context(cpi);
1319 
1320   return AOM_CODEC_OK;
1321 }
1322