Tune bitrates and minQP thresholds for high-fps screenshare.

Raise MinQP to allow easier steady-state convergence.

Update SVC rate allocator to not waste bandwidth if there's not enough
for the highest layer.

Bug: webrtc:10257
Change-Id: Iba937bf3c224ffed256308bdb6434be8b5223f84
Reviewed-on: https://webrtc-review.googlesource.com/c/122843
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26710}
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index e001872..09d37b3 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -227,16 +227,22 @@
 
 // The selected thresholds for QVGA and VGA corresponded to a QP around 10.
 // The change in QP declined above the selected bitrates.
-static int GetMaxDefaultVideoBitrateKbps(int width, int height) {
+static int GetMaxDefaultVideoBitrateKbps(int width,
+                                         int height,
+                                         bool is_screenshare) {
+  int max_bitrate;
   if (width * height <= 320 * 240) {
-    return 600;
+    max_bitrate = 600;
   } else if (width * height <= 640 * 480) {
-    return 1700;
+    max_bitrate = 1700;
   } else if (width * height <= 960 * 540) {
-    return 2000;
+    max_bitrate = 2000;
   } else {
-    return 2500;
+    max_bitrate = 2500;
   }
+  if (is_screenshare)
+    max_bitrate = std::max(max_bitrate, 1200);
+  return max_bitrate;
 }
 
 bool GetVp9LayersFromFieldTrialGroup(size_t* num_spatial_layers,
@@ -2783,7 +2789,8 @@
   int max_bitrate_bps =
       (encoder_config.max_bitrate_bps > 0)
           ? encoder_config.max_bitrate_bps
-          : GetMaxDefaultVideoBitrateKbps(width, height) * 1000;
+          : GetMaxDefaultVideoBitrateKbps(width, height, is_screenshare_) *
+                1000;
 
   int min_bitrate_bps = GetMinVideoBitrateBps();
   if (encoder_config.simulcast_layers[0].min_bitrate_bps > 0) {
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
index 7a23325..ea1b994 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
@@ -409,7 +409,8 @@
   configurations_[0].g_pass = VPX_RC_ONE_PASS;
   // Handle resizing outside of libvpx.
   configurations_[0].rc_resize_allowed = 0;
-  configurations_[0].rc_min_quantizer = 2;
+  configurations_[0].rc_min_quantizer =
+      codec_.mode == VideoCodecMode::kScreensharing ? 12 : 2;
   if (inst->qpMax >= configurations_[0].rc_min_quantizer) {
     qp_max_ = inst->qpMax;
   }
@@ -645,7 +646,7 @@
     // Allow more screen content to be detected as static.
     libvpx_->codec_control(
         &(encoders_[i]), VP8E_SET_STATIC_THRESHOLD,
-        codec_.mode == VideoCodecMode::kScreensharing ? 300u : 1u);
+        codec_.mode == VideoCodecMode::kScreensharing ? 100u : 1u);
     libvpx_->codec_control(&(encoders_[i]), VP8E_SET_CPUUSED, cpu_speed_[i]);
     libvpx_->codec_control(
         &(encoders_[i]), VP8E_SET_TOKEN_PARTITIONS,
diff --git a/modules/video_coding/codecs/vp9/svc_config.cc b/modules/video_coding/codecs/vp9/svc_config.cc
index 1754195..138822a 100644
--- a/modules/video_coding/codecs/vp9/svc_config.cc
+++ b/modules/video_coding/codecs/vp9/svc_config.cc
@@ -24,7 +24,10 @@
 
 const size_t kMaxNumLayersForScreenSharing = 3;
 const float kMaxScreenSharingLayerFramerateFps[] = {5.0, 5.0, 30.0};
-const size_t kMaxScreenSharingLayerBitrateKbps[] = {200, 500, 1250};
+const size_t kMinScreenSharingLayerBitrateKbps[] = {30, 150, 500};
+const size_t kTargetScreenSharingLayerBitrateKbps[] = {150, 350, 1000};
+const size_t kMaxScreenSharingLayerBitrateKbps[] = {200, 500, 1000};
+
 }  // namespace
 
 std::vector<SpatialLayer> ConfigureSvcScreenSharing(size_t input_width,
@@ -42,10 +45,12 @@
     spatial_layer.maxFramerate =
         std::min(kMaxScreenSharingLayerFramerateFps[sl_idx], max_framerate_fps);
     spatial_layer.numberOfTemporalLayers = 1;
-    spatial_layer.minBitrate = static_cast<int>(kMinVp9SvcBitrateKbps);
+    spatial_layer.minBitrate =
+        static_cast<int>(kMinScreenSharingLayerBitrateKbps[sl_idx]);
     spatial_layer.maxBitrate =
         static_cast<int>(kMaxScreenSharingLayerBitrateKbps[sl_idx]);
-    spatial_layer.targetBitrate = spatial_layer.maxBitrate;
+    spatial_layer.targetBitrate =
+        static_cast<int>(kTargetScreenSharingLayerBitrateKbps[sl_idx]);
     spatial_layer.active = true;
     spatial_layers.push_back(spatial_layer);
   }
diff --git a/modules/video_coding/codecs/vp9/svc_rate_allocator.cc b/modules/video_coding/codecs/vp9/svc_rate_allocator.cc
index f6ddb1e..daa59b1 100644
--- a/modules/video_coding/codecs/vp9/svc_rate_allocator.cc
+++ b/modules/video_coding/codecs/vp9/svc_rate_allocator.cc
@@ -184,20 +184,27 @@
   return bitrate_allocation;
 }
 
+// Bit-rate is allocated in such a way, that the highest enabled layer will have
+// between min and max bitrate, and all others will have exactly target
+// bit-rate allocated.
 VideoBitrateAllocation SvcRateAllocator::GetAllocationScreenSharing(
     uint32_t total_bitrate_bps,
     size_t num_spatial_layers) const {
+  if (num_spatial_layers == 0 ||
+      total_bitrate_bps < codec_.spatialLayers[0].minBitrate * 1000) {
+    return VideoBitrateAllocation();
+  }
   VideoBitrateAllocation bitrate_allocation;
 
-  // Add next layer after bitrate of previous layer has reached its maximum.
   size_t left_bitrate_bps = total_bitrate_bps;
-  for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
+  size_t sl_idx;
+  for (sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
     const size_t min_bitrate_bps =
         codec_.spatialLayers[sl_idx].minBitrate * 1000;
-    const size_t max_bitrate_bps =
-        codec_.spatialLayers[sl_idx].maxBitrate * 1000;
+    const size_t target_bitrate_bps =
+        codec_.spatialLayers[sl_idx].targetBitrate * 1000;
 
-    const size_t bitrate_bps = std::min(left_bitrate_bps, max_bitrate_bps);
+    const size_t bitrate_bps = std::min(left_bitrate_bps, target_bitrate_bps);
     if (bitrate_bps >= min_bitrate_bps) {
       bitrate_allocation.SetBitrate(sl_idx, 0, bitrate_bps);
     } else {
@@ -207,6 +214,17 @@
     left_bitrate_bps -= bitrate_bps;
   }
 
+  if (left_bitrate_bps > 0 && sl_idx > 0) {
+    // Add leftover to the last allocated layer.
+    const size_t max_bitrate_bps =
+        codec_.spatialLayers[sl_idx - 1].maxBitrate * 1000;
+
+    const size_t bitrate_bps = std::min(
+        bitrate_allocation.GetBitrate(sl_idx - 1, 0) + left_bitrate_bps,
+        max_bitrate_bps);
+    bitrate_allocation.SetBitrate(sl_idx - 1, 0, bitrate_bps);
+  }
+
   return bitrate_allocation;
 }
 
@@ -245,7 +263,7 @@
 
   uint32_t min_bitrate_kbps = 0;
   for (size_t sl_idx = 0; sl_idx < num_spatial_layers - 1; ++sl_idx) {
-    min_bitrate_kbps += codec.spatialLayers[sl_idx].maxBitrate;
+    min_bitrate_kbps += codec.spatialLayers[sl_idx].targetBitrate;
   }
   min_bitrate_kbps += codec.spatialLayers[num_spatial_layers - 1].minBitrate;
 
diff --git a/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc b/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc
index e1e1df7..f1c6bdd 100644
--- a/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc
+++ b/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc
@@ -159,8 +159,8 @@
   EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0UL);
 
   allocation = allocator.GetAllocation(
-      (layers[0].maxBitrate + layers[1].minBitrate) * 1000, 30);
-  EXPECT_EQ(allocation.GetSpatialLayerSum(0) / 1000, layers[0].maxBitrate);
+      (layers[0].targetBitrate + layers[1].minBitrate) * 1000, 30);
+  EXPECT_EQ(allocation.GetSpatialLayerSum(0) / 1000, layers[0].targetBitrate);
   EXPECT_EQ(allocation.GetSpatialLayerSum(1) / 1000, layers[1].minBitrate);
 }
 
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc
index 5feca0b..ac9f8f9 100644
--- a/modules/video_coding/codecs/vp9/vp9_impl.cc
+++ b/modules/video_coding/codecs/vp9/vp9_impl.cc
@@ -48,7 +48,7 @@
 int kMaxNumTiles4kVideo = 8;
 
 // Maximum allowed PID difference for variable frame-rate mode.
-const int kMaxAllowedPidDIff = 8;
+const int kMaxAllowedPidDIff = 30;
 
 // Only positive speeds, range for real-time coding currently is: 5 - 8.
 // Lower means slower/better quality, higher means fastest/lower quality.
@@ -441,7 +441,8 @@
   config_->rc_dropframe_thresh = inst->VP9().frameDroppingOn ? 30 : 0;
   config_->rc_end_usage = VPX_CBR;
   config_->g_pass = VPX_RC_ONE_PASS;
-  config_->rc_min_quantizer = 2;
+  config_->rc_min_quantizer =
+      codec_.mode == VideoCodecMode::kScreensharing ? 8 : 2;
   config_->rc_max_quantizer = 52;
   config_->rc_undershoot_pct = 50;
   config_->rc_overshoot_pct = 50;