ref: 98390f2d4ed86802acd96f7b9c951cfca0aa35ed
parent: 9f291d85b6f6bf8056422bae17d98f1762bcc7e4
author: angiebird <angiebird@google.com>
date: Mon Oct 14 07:32:18 EDT 2019
Add check_transition_to_still() The behavior is the same as that of detect_transition_still, only we void using cpi and twopass->stats_in Change-Id: I07722c817d98d8e4991a0a883235a582db8b5c3c
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1804,15 +1804,38 @@
(sr_decay_rate + ((1.0 - sr_decay_rate) * zero_motion_factor)));
}
+static int get_show_idx(const TWO_PASS *twopass) {
+ return (int)(twopass->stats_in - twopass->stats_in_start);
+}
// Function to test for a condition where a complex transition is followed
// by a static section. For example in slide shows where there is a fade
// between slides. This is to help with more optimal kf and gf positioning.
+static int check_transition_to_still(const FIRST_PASS_INFO *first_pass_info,
+ int show_idx, int still_interval) {
+ int j;
+ int num_frames = fps_get_num_frames(first_pass_info);
+ if (show_idx + still_interval > num_frames) {
+ return 0;
+ }
+
+ // Look ahead a few frames to see if static condition persists...
+ for (j = 0; j < still_interval; ++j) {
+ const FIRSTPASS_STATS *stats =
+ fps_get_frame_stats(first_pass_info, show_idx + j);
+ if (stats->pcnt_inter - stats->pcnt_motion < 0.999) break;
+ }
+
+ // Only if it does do we signal a transition to still.
+ return j == still_interval;
+}
+
static int detect_transition_to_still(VP9_COMP *cpi, int frame_interval,
int still_interval,
double loop_decay_rate,
double last_decay_rate) {
- TWO_PASS *const twopass = &cpi->twopass;
+ const TWO_PASS *const twopass = &cpi->twopass;
RATE_CONTROL *const rc = &cpi->rc;
+ int show_idx = get_show_idx(twopass);
// Break clause to detect very still sections after motion
// For example a static image after a fade or other transition
@@ -1819,18 +1842,8 @@
// instead of a clean scene cut.
if (frame_interval > rc->min_gf_interval && loop_decay_rate >= 0.999 &&
last_decay_rate < 0.9) {
- int j;
-
- // Look ahead a few frames to see if static condition persists...
- for (j = 0; j < still_interval; ++j) {
- const FIRSTPASS_STATS *stats = &twopass->stats_in[j];
- if (stats >= twopass->stats_in_end) break;
-
- if (stats->pcnt_inter - stats->pcnt_motion < 0.999) break;
- }
-
- // Only if it does do we signal a transition to still.
- return j == still_interval;
+ return check_transition_to_still(&twopass->first_pass_info, show_idx,
+ still_interval);
}
return 0;
@@ -2058,7 +2071,7 @@
const FRAME_INFO *frame_info = &cpi->frame_info;
TWO_PASS *const twopass = &cpi->twopass;
const int avg_inter_frame_qindex = cpi->rc.avg_frame_qindex[INTER_FRAME];
- int arf_show_idx = (int)(twopass->stats_in - twopass->stats_in_start);
+ int arf_show_idx = get_show_idx(twopass);
return compute_arf_boost(frame_info, &twopass->first_pass_info, arf_show_idx,
f_frames, b_frames, avg_inter_frame_qindex);
}
@@ -2608,10 +2621,14 @@
// Break clause to detect very still sections after motion. For example,
// a static image after a fade or other transition.
- if (detect_transition_to_still(cpi, i, 5, loop_decay_rate,
- last_loop_decay_rate)) {
- allow_alt_ref = 0;
- break;
+ if (i > rc->min_gf_interval && loop_decay_rate >= 0.999 &&
+ last_loop_decay_rate < 0.9) {
+ int still_interval = 5;
+ if (check_transition_to_still(first_pass_info, gf_start_show_idx + i,
+ still_interval)) {
+ allow_alt_ref = 0;
+ break;
+ }
}
// Update the accumulator for second ref error difference.
@@ -2666,7 +2683,7 @@
const int avg_inter_frame_qindex = rc->avg_frame_qindex[INTER_FRAME];
// TODO(angiebird): figure out why arf's location is assigned this way
const int arf_show_idx =
- VPXMIN(gf_start_show_idx + i + 1, first_pass_info->num_frames);
+ VPXMIN(gf_start_show_idx + i + 1, fps_get_num_frames(first_pass_info));
// Calculate the boost for alt ref.
rc->gfu_boost =
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -158,6 +158,10 @@
first_pass_info->num_frames = num_frames;
}
+static INLINE int fps_get_num_frames(const FIRST_PASS_INFO *first_pass_info) {
+ return first_pass_info->num_frames;
+}
+
static INLINE const FIRSTPASS_STATS *fps_get_frame_stats(
const FIRST_PASS_INFO *first_pass_info, int show_idx) {
if (show_idx >= first_pass_info->num_frames) {