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}
This commit is contained in:
Ilya Nikolaevskiy
2019-02-14 14:44:22 +01:00
committed by Commit Bot
parent c8221fc610
commit 3a656d14dc
6 changed files with 53 additions and 21 deletions

View File

@ -409,7 +409,8 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
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 @@ int LibvpxVp8Encoder::InitAndSetControlSettings() {
// 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,

View File

@ -24,7 +24,10 @@ const size_t kMinVp9SvcBitrateKbps = 30;
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 @@ std::vector<SpatialLayer> ConfigureSvcScreenSharing(size_t input_width,
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);
}

View File

@ -184,20 +184,27 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocationNormalVideo(
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 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocationScreenSharing(
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 SvcRateAllocator::GetPaddingBitrateBps(const VideoCodec& codec) {
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;

View File

@ -159,8 +159,8 @@ TEST(SvcRateAllocatorTest, MinBitrateToGetQualityLayer) {
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);
}

View File

@ -48,7 +48,7 @@ uint8_t kUpdBufIdx[4] = {0, 0, 1, 0};
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 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
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;