Commit e5112b3a authored by paulwilkins's avatar paulwilkins
Browse files

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
parent a8a9c2bb
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment