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:
committed by
Commit Bot
parent
c8221fc610
commit
3a656d14dc
@ -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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user