ref: 7ca417f66547dc5e9e3ad36c45e147f05e66522a
parent: 806e1c9843b90a94607e1ef3673b0e094d5df551
author: Jingning Han <jingning@google.com>
date: Fri Nov 30 05:23:33 EST 2018
Simplify constant q mode qp selection Decouple the constant q mode qp selection from vbr/cbr/cq modes. Skip vp9_frame_type_qdelta() adjustment for non-ARF inter frames, instead keep using the cq-level. It improves the compresson performance: avg PSNR overall PSNR SSIM lowres -0.17% -0.20% -0.1% midres -0.21% -0.24% -0.08% hdres -0.15% -0.19% -0.04% Change-Id: I52fd5f8edbd3fdcbeda31ee3a6d6eb016091a7e3
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1272,14 +1272,10 @@
#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 @@
}
*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;
}
@@ -1354,6 +1389,9 @@
int q;
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) {