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