shithub: libvpx

Download patch

ref: e5112b3ae3352c4c55fb31235305f3f80f4b8f7e
parent: a8a9c2bb45868fb9009ca1ce8e9a4d14947855a3
author: paulwilkins <paulwilkins@google.com>
date: Fri May 1 12:04:52 EDT 2015

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

--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3420,6 +3420,32 @@
   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,
@@ -3562,6 +3588,14 @@
     cpi->refresh_last_frame = 1;
 
   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);