ref: 8ad23a072a56afa443b480a2626c4bccf877a313
parent: 0d1c78230618be3967bee4f71e5e00c8b2bbd8ac
parent: 18805eee6c2a0c01b045a59a6ea95a1e02ab718a
author: Marco Paniconi <marpan@google.com>
date: Fri Jun 23 17:59:31 EDT 2017
Merge "vp9: Use scene detection for CBR mode."
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3524,12 +3524,13 @@
vp9_update_noise_estimate(cpi);
- // Scene detection is used for VBR mode or screen-content case.
- // Make sure compute_source_sad_onepass is set (which handles SVC case
- // and dynamic resize).
+ // Scene detection is always used for VBR mode or screen-content case.
+ // For other cases (e.g., CBR mode) use it for 5 <= speed < 8 for now
+ // (need to check encoding time cost for doing this for speed 8).
if (cpi->compute_source_sad_onepass &&
(cpi->oxcf.rc_mode == VPX_VBR ||
- cpi->oxcf.content == VP9E_CONTENT_SCREEN))
+ cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+ (cpi->oxcf.speed >= 5 && cpi->oxcf.speed < 8)))
vp9_scene_detection_onepass(cpi);
// For 1 pass CBR SVC, only ZEROMV is allowed for spatial reference frame
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -353,6 +353,7 @@
rc->af_ratio_onepass_vbr = 10;
rc->prev_avg_source_sad_lag = 0;
rc->high_source_sad = 0;
+ rc->reset_high_source_sad = 0;
rc->high_source_sad_lagindex = -1;
rc->alt_ref_gf_group = 0;
rc->fac_active_worst_inter = 150;
@@ -585,7 +586,7 @@
// In CBR mode, this makes sure q is between oscillating Qs to prevent
// resonance.
- if (cpi->oxcf.rc_mode == VPX_CBR &&
+ if (cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.reset_high_source_sad &&
(!cpi->oxcf.gf_cbr_boost_pct ||
!(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)) &&
(cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) &&
@@ -679,7 +680,8 @@
int active_worst_quality;
int ambient_qp;
unsigned int num_frames_weight_key = 5 * cpi->svc.number_temporal_layers;
- if (cm->frame_type == KEY_FRAME) return rc->worst_quality;
+ if (cm->frame_type == KEY_FRAME || rc->reset_high_source_sad)
+ return rc->worst_quality;
// For ambient_qp we use minimum of avg_frame_qindex[KEY_FRAME/INTER_FRAME]
// for the first few frames following key frame. These are both initialized
// to worst_quality and updated with (3/4, 1/4) average in postencode_update.
@@ -1464,6 +1466,7 @@
if (oxcf->pass == 0) {
if (cm->frame_type != KEY_FRAME) compute_frame_low_motion(cpi);
}
+ if (cm->frame_type != KEY_FRAME) rc->reset_high_source_sad = 0;
}
void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) {
@@ -2330,6 +2333,23 @@
rc->avg_source_sad[lagframe_idx] = avg_sad;
}
}
+ }
+ // For CBR non-screen content mode, check if we should reset the rate
+ // control. Reset is done if high_source_sad is detected and the rate
+ // control is at very low QP with rate correction factor at min level.
+ if (cpi->oxcf.rc_mode == VPX_CBR &&
+ cpi->oxcf.content != VP9E_CONTENT_SCREEN && !cpi->use_svc) {
+ if (rc->high_source_sad && rc->last_q[INTER_FRAME] == rc->best_quality &&
+ rc->avg_frame_qindex[INTER_FRAME] < (rc->best_quality << 1) &&
+ rc->rate_correction_factors[INTER_NORMAL] == MIN_BPB_FACTOR) {
+ rc->rate_correction_factors[INTER_NORMAL] = 0.5;
+ rc->avg_frame_qindex[INTER_FRAME] = rc->worst_quality;
+ rc->buffer_level = rc->optimal_buffer_level;
+ rc->bits_off_target = rc->optimal_buffer_level;
+ rc->reset_high_source_sad = 1;
+ }
+ if (cm->frame_type != KEY_FRAME && rc->reset_high_source_sad)
+ rc->this_frame_target = rc->avg_frame_bandwidth;
}
// For VBR, under scene change/high content change, force golden refresh.
if (cpi->oxcf.rc_mode == VPX_VBR && cm->frame_type != KEY_FRAME &&
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -169,6 +169,7 @@
int avg_frame_low_motion;
int af_ratio_onepass_vbr;
int force_qpmin;
+ int reset_high_source_sad;
} RATE_CONTROL;
struct VP9_COMP;