ref: 41d3331d423c5dc08ea582316262492f29f4d623
parent: ea1d0a6b53e83c3f2e89aac06d47e39123f706a4
author: paulwilkins <paulwilkins@google.com>
date: Mon Jan 15 07:00:01 EST 2018
Further change to code detecting slide transitions. Eliminate false positives in previous patch. The previous patch did a good job of detecting slide transitions but in discussions a number of situations were identified that might trigger harmful false positives. This risk seems to be born out by some testing on a wider YT set done by yclin@. This patch adds an additional clause that requires that the best case inter and intra error for the frame are very similar,meaning it is almost as easy to code a key frame as an inter frame. This will certainly prevent the false positive conditions that Jim and I discussed and even if one does occur it should not be very damaging. The down side is that this clause may mean that we still miss some real slide transitions, especially if the images are small and similar. If this proves to be the case then some further adjustment of the threshold may be required. However, in the specific problem sample provided we do trap every transition correctly. Change-Id: I7e5e79e52dc09bc47917565bf00cc44e5cddd44c
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2699,13 +2699,24 @@
#endif
}
+// Intra / Inter threshold very low
+#define VERY_LOW_II 1.5
+// Clean slide transitions we expect a sharp single frame spike in error.
+#define ERROR_SPIKE 5.0
+
// Slide show transition detection.
// Tests for case where there is very low error either side of the current frame
// but much higher just for this frame. This can help detect key frames in
// slide shows even where the slides are pictures of different sizes.
+// Also requires that intra and inter errors are very similar to help eliminate
+// harmful false positives.
// It will not help if the transition is a fade or other multi-frame effect.
-static int slide_transition(double this_err, double last_err, double next_err) {
- return (this_err > (last_err * 5.0)) && (this_err > (next_err * 5.0));
+static int slide_transition(const FIRSTPASS_STATS *this_frame,
+ const FIRSTPASS_STATS *last_frame,
+ const FIRSTPASS_STATS *next_frame) {
+ return (this_frame->intra_error < (this_frame->coded_error * VERY_LOW_II)) &&
+ (this_frame->coded_error > (last_frame->coded_error * ERROR_SPIKE)) &&
+ (this_frame->coded_error > (next_frame->coded_error * ERROR_SPIKE));
}
// Threshold for use of the lagging second reference frame. High second ref
@@ -2752,8 +2763,7 @@
if ((this_frame->pcnt_second_ref < SECOND_REF_USEAGE_THRESH) &&
(next_frame->pcnt_second_ref < SECOND_REF_USEAGE_THRESH) &&
((this_frame->pcnt_inter < VERY_LOW_INTER_THRESH) ||
- (slide_transition(this_frame->coded_error, last_frame->coded_error,
- next_frame->coded_error)) ||
+ (slide_transition(this_frame, last_frame, next_frame)) ||
((pcnt_intra > MIN_INTRA_LEVEL) &&
(pcnt_intra > (INTRA_VS_INTER_THRESH * modified_pcnt_inter)) &&
((this_frame->intra_error /