ref: 958f372509a7678d787cffeed40e7886a116e27a
parent: 6261fcf3073f190ca9d05a96873032acdf417c9e
author: Marco <[email protected]>
date: Thu Feb 18 07:16:01 EST 2016
vp9: 1 pass vbr real-time mode: Adjust gf refresh for scene change. Use the existing scene/content change detection to better update/adjust golden frame refresh. Change only affects 1 pass real-time vbr mode, speed >=5. Change-Id: I2963a5bb7ca4a19f8cf8511b0a925e502f60e014
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3363,11 +3363,13 @@
(cpi->oxcf.pass == 0));
// Avoid scaling last_source unless its needed.
- // Last source is currently only used for screen-content mode,
- // if partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
+ // Last source is needed if vp9_avg_source_sad() is used, or if
+ // partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
// estimation is enabled.
if (cpi->unscaled_last_source != NULL &&
(cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+ (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_VBR &&
+ cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5) ||
cpi->sf.partition_search_type == SOURCE_VAR_BASED_PARTITION ||
cpi->noise_estimate.enabled))
cpi->Last_Source = vp9_scale_if_required(cm,
@@ -3377,10 +3379,12 @@
vp9_update_noise_estimate(cpi);
if (cpi->oxcf.pass == 0 &&
- cpi->oxcf.rc_mode == VPX_CBR &&
+ cpi->oxcf.mode == REALTIME &&
+ cpi->oxcf.speed >= 5 &&
cpi->resize_state == 0 &&
cm->frame_type != KEY_FRAME &&
- cpi->oxcf.content == VP9E_CONTENT_SCREEN)
+ (cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+ cpi->oxcf.rc_mode == VPX_VBR))
vp9_avg_source_sad(cpi);
// TODO(wonkap/marpan): For 1 pass SVC, since only ZERMOV is allowed for
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -2017,6 +2017,8 @@
const int last_src_ystride = cpi->Last_Source->y_stride;
int sbi_row, sbi_col;
const BLOCK_SIZE bsize = BLOCK_64X64;
+ const uint32_t min_thresh = 4000;
+ float thresh = 8.0f;
// Loop over sub-sample of frame, and compute average sad over 64x64 blocks.
uint64_t avg_sad = 0;
int num_samples = 0;
@@ -2047,12 +2049,30 @@
// between current and the previous frame value(s). Use a minimum threshold
// for cases where there is small change from content that is completely
// static.
- if (avg_sad > VPXMAX(4000, (rc->avg_source_sad << 3)) &&
+ if (cpi->oxcf.rc_mode == VPX_VBR) {
+ thresh = 2.5f;
+ }
+ if (avg_sad >
+ VPXMAX(min_thresh, (unsigned int)(rc->avg_source_sad * thresh)) &&
rc->frames_since_key > 1)
rc->high_source_sad = 1;
else
rc->high_source_sad = 0;
rc->avg_source_sad = (rc->avg_source_sad + avg_sad) >> 1;
+ // For VBR, under scene change/high content change, force golden refresh.
+ if (cpi->oxcf.rc_mode == VPX_VBR &&
+ rc->high_source_sad &&
+ cpi->refresh_golden_frame == 0 &&
+ cpi->ext_refresh_frame_flags_pending == 0) {
+ int target;
+ cpi->refresh_golden_frame = 1;
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval >> 1;
+ if (rc->frames_till_gf_update_due > rc->frames_to_key)
+ rc->frames_till_gf_update_due = rc->frames_to_key;
+ rc->gfu_boost = DEFAULT_GF_BOOST;
+ target = calc_pframe_target_size_one_pass_vbr(cpi);
+ vp9_rc_set_frame_target(cpi, target);
+ }
}
}