]> granicus.if.org Git - libvpx/commitdiff
Simplify constant q mode qp selection
authorJingning Han <jingning@google.com>
Fri, 30 Nov 2018 18:23:33 +0000 (10:23 -0800)
committerJingning Han <jingning@google.com>
Fri, 30 Nov 2018 18:23:33 +0000 (10:23 -0800)
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

vp9/encoder/vp9_ratectrl.c

index 6c03bb3c1bb1983fd0a3c06ade989a45a9016aef..396ba02692adb5341a5d0d098e6d3b09115bebbb 100644 (file)
@@ -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