Fix bug in SvcRateAllocator capping to VideoCodec.maxBitrate

When allocating bitrate, some parts of the coded directly uses the bitrate parameter, while others lets it be capped by VideoCodec.maxBitrate. This may result in an inconsistency between expected and actual number of temporal layers, causing a crash.

Even better would be to update VideoCodecInitializer to not create
VideoCodec instances where there's not enough maxBitrate to activate
all spatial layers - but that's a much more complex issue.

Bug: chromium:1423365
Change-Id: Ic74b68261ea6043f1795accdd9864319ab535435
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298041
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39593}
This commit is contained in:
Erik Språng 2023-03-17 14:14:04 +01:00 committed by WebRTC LUCI CQ
parent 2d3b294e49
commit e94dcefbd4
2 changed files with 17 additions and 3 deletions

View File

@ -253,8 +253,7 @@ VideoBitrateAllocation SvcRateAllocator::Allocate(
hysteresis_factor = experiment_settings_.GetVideoHysteresisFactor();
}
DataRate stable_rate =
std::min(parameters.total_bitrate, parameters.stable_bitrate);
DataRate stable_rate = std::min(total_bitrate, parameters.stable_bitrate);
// First check if bitrate has grown large enough to enable new layers.
size_t num_enabled_with_hysteresis =
FindNumEnabledLayers(stable_rate / hysteresis_factor);
@ -266,7 +265,7 @@ VideoBitrateAllocation SvcRateAllocator::Allocate(
std::min(last_active_layer_count_, FindNumEnabledLayers(stable_rate));
}
} else {
num_spatial_layers = FindNumEnabledLayers(parameters.total_bitrate);
num_spatial_layers = FindNumEnabledLayers(total_bitrate);
}
last_active_layer_count_ = num_spatial_layers;

View File

@ -361,6 +361,21 @@ TEST(SvcRateAllocatorTest, UsesScalabilityModeToGetNumberOfLayers) {
EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0u);
}
TEST(SvcRateAllocatorTest, CapsAllocationToMaxBitrate) {
VideoCodec codec = Configure(1280, 720, 3, 3, false);
codec.maxBitrate = 70; // Cap the overall max bitrate to 70kbps.
SvcRateAllocator allocator = SvcRateAllocator(codec);
// Allocate 3Mbps which should be enough for all layers.
VideoBitrateAllocation allocation =
allocator.Allocate(VideoBitrateAllocationParameters(3'000'000, 30));
// The 3Mbps should be capped to 70kbps, so only first layer is active.
EXPECT_EQ(allocation.GetSpatialLayerSum(0), 70'000u);
EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0u);
EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0u);
}
class SvcRateAllocatorTestParametrizedContentType
: public ::testing::Test,
public ::testing::WithParamInterface<bool> {