Change to calculation of rc_factor. This change has a modest negative impact on metrics both when the undershoot and overshoot % are set to 100 and when it are set to 25. However, it substantially improves rate accuracy for the vast majority clips in all our test sets. The trade off of improved rate accuracy vs metrics impact seems to be good and there are metrics gains if the os/us % (pre-patch) is adjusted so that pre and post patch encodes have more comparable rate accuracy. The following shows results comparing metrics before vs after this patch in different scenarios. Results show av psnr, ov psnr, ssim and psnr-hvs respectively for the low res, ugc360, midres and hd res test sets. 100% os/us 0.120 0.168 0.228 0.093 0.128 0.395 0.257 0.194 0.167 0.347 0.186 0.155 0.123 0.168 0.204 0.105 25% os/us 0.070 0.099 0.165 0.058 0.087 0.275 0.190 0.152 0.201 0.331 0.126 0.255 0.226 0.506 0.584 0.240 In both these cases the rate accuracy is better in the vast majority of clips. (e.g. 32/40 better vs 1/40 worse and 7/40 neutral for low res 100% os/us). old 90% os/us vs new 100% -0.592 -0.698 -0.245 -0.714 -0.427 -0.406 -0.247 -0.375 -0.150 0.023 0.080 -0.071 -1.132 -1.627 -0.917 -1.215 In this second set the rate accuracy pre-patch was improved by testing with an us/os value of 90% vs 100% with the patch. The new code still gave a net improvement in rate accuracy (3-2x as many clips better vs worse) but also substantial metrics gains. If the objective is best metrics for any given value of os/us then further adjustments may be able to accommodate this with some loss of rate accuracy. STATS_CHANGED Change-Id: Id50c8855a403dff6ee1585fe9c148050d549b1ac
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c index 4edcf30..7c95257 100644 --- a/av1/encoder/pass2_strategy.c +++ b/av1/encoder/pass2_strategy.c
@@ -771,7 +771,7 @@ #define GROUP_ADAPTIVE_MAXQ 1 #if GROUP_ADAPTIVE_MAXQ #define RC_FACTOR_MIN 0.75 -#define RC_FACTOR_MAX 1.75 +#define RC_FACTOR_MAX 1.25 #endif // GROUP_ADAPTIVE_MAXQ #define MIN_FWD_KF_INTERVAL 8 @@ -1206,13 +1206,20 @@ int tmp_q; // rc factor is a weight factor that corrects for local rate control drift. double rc_factor = 1.0; - if (rc->rate_error_estimate > 0) { - rc_factor = AOMMAX(RC_FACTOR_MIN, - (double)(100 - rc->rate_error_estimate) / 100.0); - } else { - rc_factor = AOMMIN(RC_FACTOR_MAX, - (double)(100 - rc->rate_error_estimate) / 100.0); + int64_t bits = AOMMIN(rc->total_actual_bits, cpi->twopass.bits_left); + + if (bits > 0) { + int rate_error; + + rate_error = (int)((rc->vbr_bits_off_target * 100) / bits); + rate_error = clamp(rate_error, -100, 100); + if (rate_error > 0) { + rc_factor = AOMMAX(RC_FACTOR_MIN, (double)(100 - rate_error) / 100.0); + } else { + rc_factor = AOMMIN(RC_FACTOR_MAX, (double)(100 - rate_error) / 100.0); + } } + tmp_q = get_twopass_worst_quality( cpi, group_av_err, (group_av_skip_pct + group_av_inactive_zone), vbr_group_bits_per_frame, rc_factor);