ref: d2c9d92ce5c8baed705e8107cffb18696074094a
parent: 5461ec55012ad1c24094993d2634af323c7ccffa
parent: e458ca3d52dbe9bf79ee31c712e3d87e751c5307
author: Jingning Han <jingning@google.com>
date: Mon Mar 18 10:11:18 EDT 2019
Merge "Improve key frame detection"
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2749,11 +2749,54 @@
(this_frame->coded_error > (next_frame->coded_error * ERROR_SPIKE));
}
+// This test looks for anomalous changes in the nature of the intra signal
+// related to the previous and next frame as an indicator for coding a key
+// frame. This test serves to detect some additional scene cuts,
+// especially in lowish motion and low contrast sections, that are missed
+// by the other tests.
+static int intra_step_transition(const FIRSTPASS_STATS *this_frame,
+ const FIRSTPASS_STATS *last_frame,
+ const FIRSTPASS_STATS *next_frame) {
+ double last_ii_ratio;
+ double this_ii_ratio;
+ double next_ii_ratio;
+ double last_pcnt_intra = 1.0 - last_frame->pcnt_inter;
+ double this_pcnt_intra = 1.0 - this_frame->pcnt_inter;
+ double next_pcnt_intra = 1.0 - next_frame->pcnt_inter;
+ double mod_this_intra = this_pcnt_intra + this_frame->pcnt_neutral;
+
+ // Calculate ii ratio for this frame last frame and next frame.
+ last_ii_ratio =
+ last_frame->intra_error / DOUBLE_DIVIDE_CHECK(last_frame->coded_error);
+ this_ii_ratio =
+ this_frame->intra_error / DOUBLE_DIVIDE_CHECK(this_frame->coded_error);
+ next_ii_ratio =
+ next_frame->intra_error / DOUBLE_DIVIDE_CHECK(next_frame->coded_error);
+
+ // Return true the intra/inter ratio for the current frame is
+ // low but better in the next and previous frame and the relative useage of
+ // intra in the current frame is markedly higher than the last and next frame.
+ if ((this_ii_ratio < 2.0) && (last_ii_ratio > 2.25) &&
+ (next_ii_ratio > 2.25) && (this_pcnt_intra > (3 * last_pcnt_intra)) &&
+ (this_pcnt_intra > (3 * next_pcnt_intra)) &&
+ ((this_pcnt_intra > 0.075) || (mod_this_intra > 0.85))) {
+ return 1;
+ // Very low inter intra ratio (i.e. not much gain from inter coding), most
+ // blocks neutral on coding method and better inter prediction either side
+ } else if ((this_ii_ratio < 1.25) && (mod_this_intra > 0.85) &&
+ (this_ii_ratio < last_ii_ratio * 0.9) &&
+ (this_ii_ratio < next_ii_ratio * 0.9)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
// Minimum % intra coding observed in first pass (1.0 = 100%)
#define MIN_INTRA_LEVEL 0.25
// Threshold for use of the lagging second reference frame. Scene cuts do not
// usually have a high second ref useage.
-#define SECOND_REF_USEAGE_THRESH 0.125
+#define SECOND_REF_USEAGE_THRESH 0.2
// Hard threshold where the first pass chooses intra for almost all blocks.
// In such a case even if the frame is not a scene cut coding a key frame
// may be a good option.
@@ -2780,8 +2823,9 @@
(this_frame->pcnt_second_ref < SECOND_REF_USEAGE_THRESH) &&
((this_frame->pcnt_inter < VERY_LOW_INTER_THRESH) ||
(slide_transition(this_frame, last_frame, next_frame)) ||
- (((this_frame->coded_error > (next_frame->coded_error * 1.1)) &&
- (this_frame->coded_error > (last_frame->coded_error * 1.1))) &&
+ (intra_step_transition(this_frame, last_frame, next_frame)) ||
+ (((this_frame->coded_error > (next_frame->coded_error * 1.2)) &&
+ (this_frame->coded_error > (last_frame->coded_error * 1.2))) &&
(pcnt_intra > MIN_INTRA_LEVEL) &&
((pcnt_intra + this_frame->pcnt_neutral) > 0.5) &&
((this_frame->intra_error /