shithub: libvpx

Download patch

ref: cd260eba10b9155f6e6086c999bd4c9d3ca6c706
parent: 0702d5ab27723162d0167006ef93010649c94895
author: Jerome Jiang <jianj@google.com>
date: Tue Jun 29 10:48:35 EDT 2021

Add cyclic refresh to vp9 rtc external ratecontrol

Change-Id: Ia2a881399aa31ca0f34481b975362ddd4ad87f1c

--- a/test/ratectrl_rtc_test.cc
+++ b/test/ratectrl_rtc_test.cc
@@ -127,6 +127,7 @@
     rc_cfg_.max_quantizers[0] = 52;
     rc_cfg_.min_quantizers[0] = 2;
     rc_cfg_.rc_mode = rc_mode;
+    rc_cfg_.aq_mode = aq_mode_;
 
     // Encoder settings for ground truth.
     cfg_.g_w = 1280;
@@ -364,7 +365,7 @@
 
 TEST_P(RcInterfaceSvcTest, Svc) { RunSvc(); }
 
-VP9_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0),
+VP9_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0, 3),
                            ::testing::Values(VPX_CBR, VPX_VBR));
 VP9_INSTANTIATE_TEST_SUITE(RcInterfaceSvcTest, ::testing::Values(0));
 }  // namespace
--- a/vp9/encoder/vp9_aq_cyclicrefresh.c
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.c
@@ -516,7 +516,8 @@
     cr->rate_ratio_qdelta = 3.0;
   } else {
     cr->rate_ratio_qdelta = 2.0;
-    if (cpi->noise_estimate.enabled && cpi->noise_estimate.level >= kMedium) {
+    if (cr->content_mode && cpi->noise_estimate.enabled &&
+        cpi->noise_estimate.level >= kMedium) {
       // Reduce the delta-qp if the estimated source noise is above threshold.
       cr->rate_ratio_qdelta = 1.7;
       cr->rate_boost_fac = 13;
--- a/vp9/ratectrl_rtc.cc
+++ b/vp9/ratectrl_rtc.cc
@@ -11,6 +11,7 @@
 
 #include <new>
 
+#include "vp9/common/vp9_common.h"
 #include "vp9/encoder/vp9_encoder.h"
 #include "vp9/encoder/vp9_picklpf.h"
 #include "vpx/vp8cx.h"
@@ -28,6 +29,15 @@
     return nullptr;
   }
   rc_api->InitRateControl(cfg);
+  if (cfg.aq_mode) {
+    VP9_COMP *const cpi = rc_api->cpi_;
+    cpi->segmentation_map = static_cast<uint8_t *>(
+        vpx_calloc(cpi->common.mi_rows * cpi->common.mi_cols,
+                   sizeof(*cpi->segmentation_map)));
+    cpi->cyclic_refresh =
+        vp9_cyclic_refresh_alloc(cpi->common.mi_rows, cpi->common.mi_cols);
+    cpi->cyclic_refresh->content_mode = 0;
+  }
   return rc_api;
 }
 
@@ -42,7 +52,7 @@
   oxcf->bit_depth = cm->bit_depth;
   oxcf->rc_mode = rc_cfg.rc_mode;
   oxcf->pass = 0;
-  oxcf->aq_mode = NO_AQ;
+  oxcf->aq_mode = rc_cfg.aq_mode ? CYCLIC_REFRESH_AQ : NO_AQ;
   oxcf->content = VP9E_CONTENT_DEFAULT;
   oxcf->drop_frames_water_mark = 0;
   cm->current_video_frame = 0;
@@ -49,6 +59,7 @@
   rc->kf_boost = DEFAULT_KF_BOOST;
 
   UpdateRateControl(rc_cfg);
+  vp9_set_mb_mi(cm, cm->width, cm->height);
 
   cpi_->use_svc = (cpi_->svc.number_spatial_layers > 1 ||
                    cpi_->svc.number_temporal_layers > 1)
@@ -146,6 +157,8 @@
       cpi_->svc.number_temporal_layers == 1) {
     int target = 0;
     if (cpi_->oxcf.rc_mode == VPX_CBR) {
+      if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
+        vp9_cyclic_refresh_update_parameters(cpi_);
       if (frame_is_intra_only(cm))
         target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_);
       else
@@ -156,6 +169,8 @@
         cpi_->rc.frames_to_key = cpi_->oxcf.key_freq;
       }
       vp9_set_gf_update_one_pass_vbr(cpi_);
+      if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
+        vp9_cyclic_refresh_update_parameters(cpi_);
       if (frame_is_intra_only(cm))
         target = vp9_calc_iframe_target_size_one_pass_vbr(cpi_);
       else
@@ -171,6 +186,8 @@
   int bottom_index, top_index;
   cpi_->common.base_qindex =
       vp9_rc_pick_q_and_bounds(cpi_, &bottom_index, &top_index);
+
+  if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) vp9_cyclic_refresh_setup(cpi_);
 }
 
 int VP9RateControlRTC::GetQP() const { return cpi_->common.base_qindex; }
@@ -179,6 +196,14 @@
   struct loopfilter *const lf = &cpi_->common.lf;
   vp9_pick_filter_level(nullptr, cpi_, LPF_PICK_FROM_Q);
   return lf->filter_level;
+}
+
+signed char *VP9RateControlRTC::GetCyclicRefreshMap() const {
+  return cpi_->cyclic_refresh->map;
+}
+
+int *VP9RateControlRTC::GetDeltaQ() const {
+  return cpi_->cyclic_refresh->qindex_delta;
 }
 
 void VP9RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
--- a/vp9/ratectrl_rtc.h
+++ b/vp9/ratectrl_rtc.h
@@ -18,6 +18,7 @@
 #include "vp9/common/vp9_enums.h"
 #include "vp9/common/vp9_onyxc_int.h"
 #include "vp9/vp9_iface_common.h"
+#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
 #include "vp9/encoder/vp9_encoder.h"
 #include "vp9/encoder/vp9_firstpass.h"
 #include "vp9/vp9_cx_iface.h"
@@ -42,6 +43,7 @@
     framerate = 30.0;
     ss_number_layers = ts_number_layers = 1;
     rc_mode = VPX_CBR;
+    aq_mode = 0;
     vp9_zero(max_quantizers);
     vp9_zero(min_quantizers);
     vp9_zero(scaling_factor_den);
@@ -82,6 +84,7 @@
   int ts_rate_decimator[VPX_TS_MAX_LAYERS];
   // vbr, cbr
   enum vpx_rc_mode rc_mode;
+  int aq_mode;
 };
 
 struct VP9FrameParamsQpRTC {
@@ -129,6 +132,11 @@
           }
         }
       }
+      if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
+        vpx_free(cpi_->segmentation_map);
+        cpi_->segmentation_map = NULL;
+        vp9_cyclic_refresh_free(cpi_->cyclic_refresh);
+      }
       vpx_free(cpi_);
     }
   }
@@ -137,6 +145,8 @@
   // GetQP() needs to be called after ComputeQP() to get the latest QP
   int GetQP() const;
   int GetLoopfilterLevel() const;
+  signed char *GetCyclicRefreshMap() const;
+  int *GetDeltaQ() const;
   void ComputeQP(const VP9FrameParamsQpRTC &frame_params);
   // Feedback to rate control with the size of current encoded frame
   void PostEncodeUpdate(uint64_t encoded_frame_size);