From e5112b3ae3352c4c55fb31235305f3f80f4b8f7e Mon Sep 17 00:00:00 2001 From: paulwilkins Date: Fri, 1 May 2015 16:04:52 +0100 Subject: [PATCH] Skip the last frame update for some frame repeats. Where a frame appears to be a repeat of an earlier frame or frame buffer, but the first pass code does not anticipate this (usually because it is matching the GF or ARF buffer not the last frame buffer), do not update the last frame buffer. This helps ensure that the content of the last frame buffer is kept "different" where possible, and not updated to match the GF or ARF. This is particularly helpful in some animated sequences where there are groups of repeating frames. Here it has quite a big impact. However, in most of our standard test clips it has little or no impact. Change-Id: I77332ee1a69f9ffc0c6080bfeb811c43fd8828e6 --- vp9/encoder/vp9_encoder.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index a1018ad..5d500e9 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3420,6 +3420,32 @@ int setup_interp_filter_search_mask(VP9_COMP *cpi) { return mask; } +#define EXTREME_UNDERSHOOT_RATIO 10 +#define LOW_ABSOLUTE_RATE_PER_MB 2 +static int frame_repeat_detected(VP9_COMP *cpi) { + RATE_CONTROL *const rc = &cpi->rc; + int repeat_detected = 0; + int low_rate = LOW_ABSOLUTE_RATE_PER_MB * cpi->common.MBs; + + // Detects an "unexpected frame buffer repeat". + // This status is not strictly a frame repeat but is triggered when + // a frame hugely undershoots the expected first pass target and in + // absolute terms the rate is very low. A typical situation where this may + // occurr is if the frame, whilst not matching the previous frame, DOES very + // closely match the contents of one of the other frame buffers. A genuinely + // static scene should not normally trigger this case as the last frame + // will also match and the predicted rate will thus be low. + if (!frame_is_kf_gf_arf(cpi) && !cpi->rc.is_src_frame_alt_ref && + rc->projected_frame_size) { + if ((rc->projected_frame_size < low_rate) && + ((rc->base_frame_target / rc->projected_frame_size) >= + EXTREME_UNDERSHOOT_RATIO)) { + repeat_detected = 1; + } + } + return repeat_detected; +} + static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, uint8_t *dest, @@ -3563,6 +3589,14 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cm->frame_to_show = get_frame_new_buffer(cm); + // Test for special case where the frame appears to be a repeat of an earlier + // encoded frame buffer but this was not predicted by the first pass. + // In this case do not update the last frame buffer. + if ((cpi->oxcf.pass == 2) && (frame_is_intra_only(cm) == 0) && + frame_repeat_detected(cpi)) { + cpi->refresh_last_frame = 0; + } + // Pick the loop filter level for the frame. loopfilter_frame(cpi, cm); -- 2.7.4