Update VideoBitrateAllocator allocate to take a struct with more fields

We want to evaluate more data in order to make better choices in the
bitrate allocators.
In order to freely update the parameter list without
breaking the API many times for projects customizing them, we'll use a
struct instead.

Bug: webrtc:10126
Change-Id: I443f86781c5134950294cdd1e3197a47447cf973
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/141418
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28748}
This commit is contained in:
Florent Castelli
2019-08-02 15:16:28 +02:00
committed by Commit Bot
parent 9a9f18a736
commit 8bbdb5b9bd
25 changed files with 232 additions and 112 deletions

View File

@ -294,8 +294,9 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst,
}
SimulcastRateAllocator init_allocator(codec_);
VideoBitrateAllocation allocation = init_allocator.GetAllocation(
codec_.startBitrate * 1000, codec_.maxFramerate);
VideoBitrateAllocation allocation =
init_allocator.Allocate(VideoBitrateAllocationParameters(
DataRate::kbps(codec_.startBitrate), codec_.maxFramerate));
SetRates(RateControlParameters(allocation, codec_.maxFramerate));
return WEBRTC_VIDEO_CODEC_OK;
}

View File

@ -305,8 +305,9 @@ void VideoProcessor::ProcessFrame() {
void VideoProcessor::SetRates(size_t bitrate_kbps, double framerate_fps) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
framerate_fps_ = framerate_fps;
bitrate_allocation_ = bitrate_allocator_->GetAllocation(
static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_);
bitrate_allocation_ =
bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_));
encoder_->SetRates(
VideoEncoder::RateControlParameters(bitrate_allocation_, framerate_fps_));
}

View File

@ -96,7 +96,9 @@ std::vector<uint32_t> GetTemporalLayerRates(int target_bitrate_kbps,
codec.simulcastStream[0].numberOfTemporalLayers = num_temporal_layers;
codec.simulcastStream[0].active = true;
SimulcastRateAllocator allocator(codec);
return allocator.GetAllocation(target_bitrate_kbps, framerate_fps)
return allocator
.Allocate(
VideoBitrateAllocationParameters(target_bitrate_kbps, framerate_fps))
.GetTemporalLayerAllocation(0);
}

View File

@ -642,8 +642,9 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
// at position 0 and they have highest resolution at position 0.
const size_t stream_idx_cfg_0 = encoders_.size() - 1;
SimulcastRateAllocator init_allocator(codec_);
VideoBitrateAllocation allocation = init_allocator.GetAllocation(
inst->startBitrate * 1000, inst->maxFramerate);
VideoBitrateAllocation allocation =
init_allocator.Allocate(VideoBitrateAllocationParameters(
inst->startBitrate * 1000, inst->maxFramerate));
std::vector<uint32_t> stream_bitrates;
for (int i = 0; i == 0 || i < inst->numberOfSimulcastStreams; ++i) {
uint32_t bitrate = allocation.GetSpatialLayerSum(i) / 1000;

View File

@ -103,18 +103,18 @@ SvcRateAllocator::SvcRateAllocator(const VideoCodec& codec) : codec_(codec) {
RTC_DCHECK_GT(codec.VP9().numberOfTemporalLayers, 0u);
}
VideoBitrateAllocation SvcRateAllocator::GetAllocation(
uint32_t total_bitrate_bps,
uint32_t framerate_fps) {
VideoBitrateAllocation SvcRateAllocator::Allocate(
VideoBitrateAllocationParameters parameters) {
DataRate total_bitrate = parameters.total_bitrate;
if (codec_.maxBitrate != 0) {
total_bitrate_bps = std::min(total_bitrate_bps, codec_.maxBitrate * 1000);
total_bitrate = std::min(total_bitrate, DataRate::kbps(codec_.maxBitrate));
}
if (codec_.spatialLayers[0].targetBitrate == 0) {
// Delegate rate distribution to VP9 encoder wrapper if bitrate thresholds
// are not set.
VideoBitrateAllocation bitrate_allocation;
bitrate_allocation.SetBitrate(0, 0, total_bitrate_bps);
bitrate_allocation.SetBitrate(0, 0, total_bitrate.bps());
return bitrate_allocation;
}
@ -124,9 +124,9 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocation(
}
if (codec_.mode == VideoCodecMode::kRealtimeVideo) {
return GetAllocationNormalVideo(total_bitrate_bps, num_spatial_layers);
return GetAllocationNormalVideo(total_bitrate.bps(), num_spatial_layers);
} else {
return GetAllocationScreenSharing(total_bitrate_bps, num_spatial_layers);
return GetAllocationScreenSharing(total_bitrate.bps(), num_spatial_layers);
}
}

View File

@ -26,8 +26,8 @@ class SvcRateAllocator : public VideoBitrateAllocator {
public:
explicit SvcRateAllocator(const VideoCodec& codec);
VideoBitrateAllocation GetAllocation(uint32_t total_bitrate_bps,
uint32_t framerate_fps) override;
VideoBitrateAllocation Allocate(
VideoBitrateAllocationParameters parameters) override;
static uint32_t GetMaxBitrateBps(const VideoCodec& codec);
static uint32_t GetPaddingBitrateBps(const VideoCodec& codec);

View File

@ -52,7 +52,8 @@ TEST(SvcRateAllocatorTest, SingleLayerFor320x180Input) {
VideoCodec codec = Configure(320, 180, 3, 3, false);
SvcRateAllocator allocator = SvcRateAllocator(codec);
VideoBitrateAllocation allocation = allocator.GetAllocation(1000 * 1000, 30);
VideoBitrateAllocation allocation =
allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0u);
@ -62,7 +63,8 @@ TEST(SvcRateAllocatorTest, TwoLayersFor640x360Input) {
VideoCodec codec = Configure(640, 360, 3, 3, false);
SvcRateAllocator allocator = SvcRateAllocator(codec);
VideoBitrateAllocation allocation = allocator.GetAllocation(1000 * 1000, 30);
VideoBitrateAllocation allocation =
allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
EXPECT_GT(allocation.GetSpatialLayerSum(1), 0u);
@ -73,7 +75,8 @@ TEST(SvcRateAllocatorTest, ThreeLayersFor1280x720Input) {
VideoCodec codec = Configure(1280, 720, 3, 3, false);
SvcRateAllocator allocator = SvcRateAllocator(codec);
VideoBitrateAllocation allocation = allocator.GetAllocation(1000 * 1000, 30);
VideoBitrateAllocation allocation =
allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
EXPECT_GT(allocation.GetSpatialLayerSum(1), 0u);
@ -87,8 +90,8 @@ TEST(SvcRateAllocatorTest,
const SpatialLayer* layers = codec.spatialLayers;
VideoBitrateAllocation allocation =
allocator.GetAllocation(layers[0].minBitrate * 1000 / 2, 30);
VideoBitrateAllocation allocation = allocator.Allocate(
VideoBitrateAllocationParameters(layers[0].minBitrate * 1000 / 2, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
EXPECT_LT(allocation.GetSpatialLayerSum(0), layers[0].minBitrate * 1000);
@ -104,8 +107,9 @@ TEST(SvcRateAllocatorTest, Disable640x360Layer) {
size_t min_bitrate_for_640x360_layer_kbps =
layers[0].minBitrate + layers[1].minBitrate;
VideoBitrateAllocation allocation = allocator.GetAllocation(
min_bitrate_for_640x360_layer_kbps * 1000 - 1, 30);
VideoBitrateAllocation allocation =
allocator.Allocate(VideoBitrateAllocationParameters(
min_bitrate_for_640x360_layer_kbps * 1000 - 1, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0u);
@ -120,8 +124,9 @@ TEST(SvcRateAllocatorTest, Disable1280x720Layer) {
size_t min_bitrate_for_1280x720_layer_kbps =
layers[0].minBitrate + layers[1].minBitrate + layers[2].minBitrate;
VideoBitrateAllocation allocation = allocator.GetAllocation(
min_bitrate_for_1280x720_layer_kbps * 1000 - 1, 30);
VideoBitrateAllocation allocation =
allocator.Allocate(VideoBitrateAllocationParameters(
min_bitrate_for_1280x720_layer_kbps * 1000 - 1, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
EXPECT_GT(allocation.GetSpatialLayerSum(1), 0u);
@ -135,8 +140,8 @@ TEST(SvcRateAllocatorTest, BitrateIsCapped) {
const SpatialLayer* layers = codec.spatialLayers;
const uint32_t link_mbps = 100;
VideoBitrateAllocation allocation =
allocator.GetAllocation(link_mbps * 1000000, 30);
VideoBitrateAllocation allocation = allocator.Allocate(
VideoBitrateAllocationParameters(link_mbps * 1000000, 30));
EXPECT_EQ(allocation.get_sum_kbps(),
layers[0].maxBitrate + layers[1].maxBitrate + layers[2].maxBitrate);
@ -153,13 +158,13 @@ TEST(SvcRateAllocatorTest, MinBitrateToGetQualityLayer) {
EXPECT_LE(codec.VP9()->numberOfSpatialLayers, 3U);
VideoBitrateAllocation allocation =
allocator.GetAllocation(layers[0].minBitrate * 1000, 30);
VideoBitrateAllocation allocation = allocator.Allocate(
VideoBitrateAllocationParameters(layers[0].minBitrate * 1000, 30));
EXPECT_EQ(allocation.GetSpatialLayerSum(0) / 1000, layers[0].minBitrate);
EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0UL);
allocation = allocator.GetAllocation(
(layers[0].targetBitrate + layers[1].minBitrate) * 1000, 30);
allocation = allocator.Allocate(VideoBitrateAllocationParameters(
(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);
}
@ -173,8 +178,8 @@ TEST(SvcRateAllocatorTest, DeativateLayers) {
SvcRateAllocator allocator = SvcRateAllocator(codec);
VideoBitrateAllocation allocation =
allocator.GetAllocation(10 * 1000 * 1000, 30);
VideoBitrateAllocation allocation = allocator.Allocate(
VideoBitrateAllocationParameters(10 * 1000 * 1000, 30));
// Ensure layers spatial_idx < deactivated_idx are activated.
for (int spatial_idx = 0; spatial_idx < deactivated_idx; ++spatial_idx) {
@ -227,14 +232,15 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, PaddingBitrate) {
uint32_t padding_bitrate_bps = SvcRateAllocator::GetPaddingBitrateBps(codec);
VideoBitrateAllocation allocation =
allocator.GetAllocation(padding_bitrate_bps, 30);
VideoBitrateAllocation allocation = allocator.Allocate(
VideoBitrateAllocationParameters(padding_bitrate_bps, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL);
EXPECT_GT(allocation.GetSpatialLayerSum(2), 0UL);
// Allocate 90% of padding bitrate. Top layer should be disabled.
allocation = allocator.GetAllocation(9 * padding_bitrate_bps / 10, 30);
allocation = allocator.Allocate(
VideoBitrateAllocationParameters(9 * padding_bitrate_bps / 10, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL);
EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL);
@ -243,12 +249,14 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, PaddingBitrate) {
codec.spatialLayers[2].active = false;
padding_bitrate_bps = SvcRateAllocator::GetPaddingBitrateBps(codec);
allocation = allocator.GetAllocation(padding_bitrate_bps, 30);
allocation = allocator.Allocate(
VideoBitrateAllocationParameters(padding_bitrate_bps, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL);
EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL);
allocation = allocator.GetAllocation(9 * padding_bitrate_bps / 10, 30);
allocation = allocator.Allocate(
VideoBitrateAllocationParameters(9 * padding_bitrate_bps / 10, 30));
EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0UL);
EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL);

View File

@ -659,8 +659,9 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
}
SvcRateAllocator init_allocator(codec_);
current_bitrate_allocation_ = init_allocator.GetAllocation(
inst->startBitrate * 1000, inst->maxFramerate);
current_bitrate_allocation_ =
init_allocator.Allocate(VideoBitrateAllocationParameters(
inst->startBitrate * 1000, inst->maxFramerate));
if (!SetSvcRates(current_bitrate_allocation_)) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}