Index: source/libvpx/vp9/encoder/vp9_ratectrl.c |
diff --git a/source/libvpx/vp9/encoder/vp9_ratectrl.c b/source/libvpx/vp9/encoder/vp9_ratectrl.c |
index 4c33ffd977b588d09c435097da67aa7c3da695cf..98095ac32648ebdc548e20d13686022a7af726f1 100644 |
--- a/source/libvpx/vp9/encoder/vp9_ratectrl.c |
+++ b/source/libvpx/vp9/encoder/vp9_ratectrl.c |
@@ -16,6 +16,7 @@ |
#include <string.h> |
#include "vpx_mem/vpx_mem.h" |
+#include "vpx_ports/mem.h" |
#include "vp9/common/vp9_alloccommon.h" |
#include "vp9/encoder/vp9_aq_cyclicrefresh.h" |
@@ -136,7 +137,7 @@ static void init_minq_luts(int *kf_low_m, int *kf_high_m, |
} |
} |
-void vp9_rc_init_minq_luts() { |
+void vp9_rc_init_minq_luts(void) { |
init_minq_luts(kf_low_motion_minq_8, kf_high_motion_minq_8, |
arfgf_low_motion_minq_8, arfgf_high_motion_minq_8, |
inter_minq_8, rtc_minq_8, VPX_BITS_8); |
@@ -491,7 +492,10 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, |
i = active_best_quality; |
do { |
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) { |
+ if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && |
+ cm->seg.enabled && |
+ cpi->svc.temporal_layer_id == 0 && |
+ cpi->svc.spatial_layer_id == 0) { |
bits_per_mb_at_this_q = |
(int)vp9_cyclic_refresh_rc_bits_per_mb(cpi, i, correction_factor); |
} else { |
@@ -1057,10 +1061,12 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, |
if (frame_is_intra_only(cm) || |
(!rc->is_src_frame_alt_ref && |
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) { |
- active_best_quality -= cpi->twopass.extend_minq; |
+ active_best_quality -= |
+ (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast); |
active_worst_quality += (cpi->twopass.extend_maxq / 2); |
} else { |
- active_best_quality -= cpi->twopass.extend_minq / 2; |
+ active_best_quality -= |
+ (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast) / 2; |
active_worst_quality += cpi->twopass.extend_maxq; |
} |
} |
@@ -1203,11 +1209,9 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { |
// this frame refreshes means next frames don't unless specified by user |
rc->frames_since_golden = 0; |
- if (cpi->oxcf.pass == 2) { |
- if (!rc->source_alt_ref_pending && |
- cpi->twopass.gf_group.rf_level[0] == GF_ARF_STD) |
- rc->source_alt_ref_active = 0; |
- } else if (!rc->source_alt_ref_pending) { |
+ // If we are not using alt ref in the up and coming group clear the arf |
+ // active flag. |
+ if (!rc->source_alt_ref_pending) { |
rc->source_alt_ref_active = 0; |
} |
@@ -1669,9 +1673,9 @@ void vp9_rc_update_framerate(VP9_COMP *cpi) { |
#define VBR_PCT_ADJUSTMENT_LIMIT 50 |
// For VBR...adjustment to the frame target based on error from previous frames |
-static void vbr_rate_correction(VP9_COMP *cpi, |
- int *this_frame_target, |
- int64_t vbr_bits_off_target) { |
+static void vbr_rate_correction(VP9_COMP *cpi, int *this_frame_target) { |
+ RATE_CONTROL *const rc = &cpi->rc; |
+ int64_t vbr_bits_off_target = rc->vbr_bits_off_target; |
int max_delta; |
double position_factor = 1.0; |
@@ -1695,6 +1699,20 @@ static void vbr_rate_correction(VP9_COMP *cpi, |
(vbr_bits_off_target < -max_delta) ? max_delta |
: (int)-vbr_bits_off_target; |
} |
+ |
+ // Fast redistribution of bits arising from massive local undershoot. |
+ // Dont do it for kf,arf,gf or overlay frames. |
+ if (!frame_is_kf_gf_arf(cpi) && !rc->is_src_frame_alt_ref && |
+ rc->vbr_bits_off_target_fast) { |
+ int one_frame_bits = MAX(rc->avg_frame_bandwidth, *this_frame_target); |
+ int fast_extra_bits; |
+ fast_extra_bits = |
+ (int)MIN(rc->vbr_bits_off_target_fast, one_frame_bits); |
+ fast_extra_bits = (int)MIN(fast_extra_bits, |
+ MAX(one_frame_bits / 8, rc->vbr_bits_off_target_fast / 8)); |
+ *this_frame_target += (int)fast_extra_bits; |
+ rc->vbr_bits_off_target_fast -= fast_extra_bits; |
+ } |
} |
void vp9_set_target_rate(VP9_COMP *cpi) { |
@@ -1703,6 +1721,6 @@ void vp9_set_target_rate(VP9_COMP *cpi) { |
// Correction to rate target based on prior over or under shoot. |
if (cpi->oxcf.rc_mode == VPX_VBR || cpi->oxcf.rc_mode == VPX_CQ) |
- vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target); |
+ vbr_rate_correction(cpi, &target_rate); |
vp9_rc_set_frame_target(cpi, target_rate); |
} |