Reset show_existing_frame for a dropped frame
In this CL, the flags 'show_existing_frame' is
reset and 'cpi->is_dropped_frame' is set for an
OVERLAY_UPDATE/INTNL_OVERLAY_UPDATE frame if the
corresponding ARF_UPDATE/INTNL_ARF_UPDATE frame
was dropped.
STATS_CHANGED expected with --drop-frame=1
BUG=aomedia:3372
Change-Id: Ie366b594d7b9e7eb276599e1bbe37d2b61b6015e
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index db0e281..85f2f95 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -1361,6 +1361,35 @@
}
frame_params.show_existing_frame &= allow_show_existing(cpi, *frame_flags);
+ // Special handling to reset 'show_existing_frame' in case of dropped
+ // frames.
+ if (oxcf->rc_cfg.drop_frames_water_mark &&
+ (gf_group->update_type[cpi->gf_frame_index] == OVERLAY_UPDATE ||
+ gf_group->update_type[cpi->gf_frame_index] == INTNL_OVERLAY_UPDATE)) {
+ // During the encode of an OVERLAY_UPDATE/INTNL_OVERLAY_UPDATE frame, loop
+ // over the gf group to check if the corresponding
+ // ARF_UPDATE/INTNL_ARF_UPDATE frame was dropped.
+ int cur_disp_idx = gf_group->display_idx[cpi->gf_frame_index];
+ for (int idx = 0; idx < cpi->gf_frame_index; idx++) {
+ if (cur_disp_idx == gf_group->display_idx[idx]) {
+ assert(IMPLIES(
+ gf_group->update_type[cpi->gf_frame_index] == OVERLAY_UPDATE,
+ gf_group->update_type[idx] == ARF_UPDATE));
+ assert(IMPLIES(gf_group->update_type[cpi->gf_frame_index] ==
+ INTNL_OVERLAY_UPDATE,
+ gf_group->update_type[idx] == INTNL_ARF_UPDATE));
+ // Reset show_existing_frame and set cpi->is_dropped_frame to true if
+ // the frame was dropped during its first encode.
+ if (gf_group->is_frame_dropped[idx]) {
+ frame_params.show_existing_frame = 0;
+ assert(!cpi->is_dropped_frame);
+ cpi->is_dropped_frame = true;
+ }
+ break;
+ }
+ }
+ }
+
// Reset show_existing_alt_ref decision to 0 after it is used.
if (gf_group->update_type[cpi->gf_frame_index] == OVERLAY_UPDATE) {
cpi->ppi->show_existing_alt_ref = 0;
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 27ae1d0..f2c2483 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3728,12 +3728,20 @@
// Never drop on key frame.
if (has_no_stats_stage(cpi) && oxcf->rc_cfg.mode == AOM_CBR &&
current_frame->frame_type != KEY_FRAME) {
+ FRAME_UPDATE_TYPE update_type =
+ cpi->ppi->gf_group.update_type[cpi->gf_frame_index];
+ (void)update_type;
+ assert(
+ IMPLIES(cpi->is_dropped_frame, (update_type == OVERLAY_UPDATE ||
+ update_type == INTNL_OVERLAY_UPDATE)));
if (av1_rc_drop_frame(cpi)) {
+ cpi->is_dropped_frame = true;
+ }
+ if (cpi->is_dropped_frame) {
av1_setup_frame_size(cpi);
av1_set_mv_search_params(cpi);
av1_rc_postencode_update_drop_frame(cpi);
release_scaled_references(cpi);
- cpi->is_dropped_frame = true;
cpi->ppi->gf_group.is_frame_dropped[cpi->gf_frame_index] = true;
// A dropped frame might not be shown but it always takes a slot in the gf
// group. Therefore, even when it is not shown, we still need to update