summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorYaowu Xu <yaowu@google.com>2014-11-18 08:52:21 -0800
committerYaowu Xu <yaowu@google.com>2014-11-18 09:05:57 -0800
commitffa06b37083d028b50f27e67ae6ed0c6ee9953bb (patch)
tree126502ce22e939244450349e98c51840efac5ec4 /vp9/encoder
parent1687c47bfdff2a4a6d2a07fb143be3f9b21824ff (diff)
downloadlibvpx-ffa06b37083d028b50f27e67ae6ed0c6ee9953bb.tar
libvpx-ffa06b37083d028b50f27e67ae6ed0c6ee9953bb.tar.gz
libvpx-ffa06b37083d028b50f27e67ae6ed0c6ee9953bb.tar.bz2
libvpx-ffa06b37083d028b50f27e67ae6ed0c6ee9953bb.zip
Prevent severe rate control errors in CBR mode
In rare cases, the interaction between rate correction factor and Q choices may cause severe oscillating frame sizes that are way off target bandwidth. This commit adds tracking of rate control results for last two frames, and use the information to prevent oscillating Q choices. Change-Id: I9a6d125a15652b9bcac0e1fec6d7a1aedc4ed97e
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_ratectrl.c22
-rw-r--r--vp9/encoder/vp9_ratectrl.h9
2 files changed, 28 insertions, 3 deletions
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index c19602a14..2390e6fb7 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -430,7 +430,8 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) {
adjustment_limit = 0.75;
break;
case 1:
- adjustment_limit = 0.125 + 0.5 * MIN(1, fabs(log10(0.01 * correction_factor)));
+ adjustment_limit = 0.25 +
+ 0.5 * MIN(1, fabs(log10(0.01 * correction_factor)));
break;
case 2:
default:
@@ -438,12 +439,21 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) {
break;
}
+ cpi->rc.q_2_frame = cpi->rc.q_1_frame;
+ cpi->rc.q_1_frame = cm->base_qindex;
+ cpi->rc.rc_2_frame = cpi->rc.rc_1_frame;
+ if (correction_factor > 110)
+ cpi->rc.rc_1_frame = -1;
+ else if (correction_factor < 90)
+ cpi->rc.rc_1_frame = 1;
+ else
+ cpi->rc.rc_1_frame = 0;
+
if (correction_factor > 102) {
// We are not already at the worst allowable quality
correction_factor = (int)(100 + ((correction_factor - 100) *
adjustment_limit));
rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
-
// Keep rate_correction_factor within limits
if (rate_correction_factor > MAX_BPB_FACTOR)
rate_correction_factor = MAX_BPB_FACTOR;
@@ -494,6 +504,14 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
}
} while (++i <= active_worst_quality);
+ // In CBR mode, this makes sure q is between oscillating Qs to prevent
+ // resonance.
+ if (cpi->oxcf.rc_mode == VPX_CBR &&
+ (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) &&
+ cpi->rc.q_1_frame != cpi->rc.q_2_frame) {
+ q = clamp(q, MIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame),
+ MAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame));
+ }
return q;
}
diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h
index 2bc5b59f2..6200b396c 100644
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -99,7 +99,14 @@ typedef struct {
int64_t starting_buffer_level;
int64_t optimal_buffer_level;
int64_t maximum_buffer_size;
- // int active_best_quality;
+ // rate control history for last frame(1) and the frame before(2).
+ // -1: undershot
+ // 1: overshoot
+ // 0: not initialized.
+ int rc_1_frame;
+ int rc_2_frame;
+ int q_1_frame;
+ int q_2_frame;
} RATE_CONTROL;
struct VP9_COMP;