summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_encoder.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index ecd15cb01..34646465a 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -4398,6 +4398,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest
int frame_over_shoot_limit;
int frame_under_shoot_limit;
int q = 0, q_low = 0, q_high = 0;
+ int last_q_attempt = 0;
int enable_acl;
#ifdef AGGRESSIVE_VBR
int qrange_adj = 1;
@@ -4413,6 +4414,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest
// passed in by the external rate control model.
// case: -1, we take VP9's decision for the max frame size.
int ext_rc_max_frame_size = 0;
+ const int orig_rc_max_frame_bandwidth = rc->max_frame_bandwidth;
#if CONFIG_RATE_CTRL
const FRAME_UPDATE_TYPE update_type =
@@ -4580,6 +4582,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest
}
if (cpi->ext_ratectrl.ready) {
+ last_q_attempt = q;
// In general, for the external rate control, we take the qindex provided
// as input and encode the frame with this qindex faithfully. However,
// in some extreme scenarios, the provided qindex leads to a massive
@@ -4597,6 +4600,10 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest
break;
}
}
+ rc->max_frame_bandwidth = ext_rc_max_frame_size;
+ // If the current frame size exceeds the ext_rc_max_frame_size,
+ // we adjust the worst qindex to meet the frame size constraint.
+ q_high = 255;
ext_rc_recode = 1;
}
#if CONFIG_RATE_CTRL
@@ -4796,6 +4803,23 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest
rc->projected_frame_size < rc->max_frame_bandwidth)
loop = 0;
+ // Special handling of external max frame size constraint
+ if (ext_rc_recode) {
+ // If the largest q is not able to meet the max frame size limit,
+ // do nothing.
+ if (rc->projected_frame_size > ext_rc_max_frame_size &&
+ last_q_attempt == 255) {
+ break;
+ }
+ // If VP9's q selection leads to a smaller q, we force it to use
+ // a larger q to better approximate the external max frame size
+ // constraint.
+ if (rc->projected_frame_size > ext_rc_max_frame_size &&
+ q <= last_q_attempt) {
+ q = VPXMIN(255, last_q_attempt + 1);
+ }
+ }
+
if (loop) {
++loop_count;
++loop_at_this_size;
@@ -4809,6 +4833,8 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest
if (loop) restore_coding_context(cpi);
} while (loop);
+ rc->max_frame_bandwidth = orig_rc_max_frame_bandwidth;
+
#ifdef AGGRESSIVE_VBR
if (two_pass_first_group_inter(cpi)) {
cpi->twopass.active_worst_quality =