summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/encoder/vp9_ratectrl.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 6c03bb3c1..396ba0269 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1272,14 +1272,10 @@ int vp9_frame_type_qdelta(const VP9_COMP *cpi, int rf_level, int q) {
#define STATIC_MOTION_THRESH 95
-static int pick_kf_q_bound_two_pass(const VP9_COMP *cpi, int *bottom_index,
- int *top_index) {
+static void pick_kf_q_bound_two_pass(const VP9_COMP *cpi, int *bottom_index,
+ int *top_index) {
const VP9_COMMON *const cm = &cpi->common;
const RATE_CONTROL *const rc = &cpi->rc;
- const VP9EncoderConfig *const oxcf = &cpi->oxcf;
- const int cq_level = get_active_cq_level_two_pass(&cpi->twopass, rc, oxcf);
-
- int q = cq_level;
int active_best_quality;
int active_worst_quality = cpi->twopass.active_worst_quality;
@@ -1338,7 +1334,46 @@ static int pick_kf_q_bound_two_pass(const VP9_COMP *cpi, int *bottom_index,
}
*top_index = active_worst_quality;
*bottom_index = active_best_quality;
+}
+
+static int rc_constant_q(const VP9_COMP *cpi, int *bottom_index, int *top_index,
+ int gf_group_index) {
+ const VP9_COMMON *const cm = &cpi->common;
+ const RATE_CONTROL *const rc = &cpi->rc;
+ const VP9EncoderConfig *const oxcf = &cpi->oxcf;
+ const GF_GROUP *gf_group = &cpi->twopass.gf_group;
+ const int is_intra_frame = frame_is_intra_only(cm);
+
+ const int cq_level = get_active_cq_level_two_pass(&cpi->twopass, rc, oxcf);
+ int q = cq_level;
+ int active_best_quality = cq_level;
+ int active_worst_quality = cq_level;
+
+ // Key frame qp decision
+ if (is_intra_frame && rc->frames_to_key > 1)
+ pick_kf_q_bound_two_pass(cpi, &active_best_quality, &active_worst_quality);
+
+ // ARF / GF qp decision
+ if (!is_intra_frame && !rc->is_src_frame_alt_ref &&
+ cpi->refresh_alt_ref_frame) {
+ active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
+
+ // Modify best quality for second level arfs. For mode VPX_Q this
+ // becomes the baseline frame q.
+ if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) {
+ const int layer_depth = gf_group->layer_depth[gf_group_index];
+ // linearly fit the frame q depending on the layer depth index from
+ // the base layer ARF.
+ active_best_quality = ((layer_depth - 1) * cq_level +
+ active_best_quality + layer_depth / 2) /
+ layer_depth;
+ }
+ }
+
+ q = active_best_quality;
+ *top_index = active_worst_quality;
+ *bottom_index = active_best_quality;
return q;
}
@@ -1355,6 +1390,9 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index,
int *inter_minq;
ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq);
+ if (oxcf->rc_mode == VPX_Q)
+ return rc_constant_q(cpi, bottom_index, top_index, gf_group_index);
+
if (frame_is_intra_only(cm)) {
if (rc->frames_to_key == 1 && oxcf->rc_mode == VPX_Q) {
// If the next frame is also a key frame or the current frame is the