webrtc/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc
Erik Språng 82fad3d513 Remove TemporalLayersFactory and associated classes
As the rate allocation has been moved into entirely into
SimulcastRateAllocator, and the listeners are thus no longer needed,
this class doesn't fill any other purpose than to determine if
ScreenshareLayers or TemporalLayers should be created for a given
simulcast stream. This can however be done just from looking at the
VideoCodec instance, so changing this into a static factory method.

Due to dependencies from upstream projects, keep the class name and
field in VideoCodec around for now.

Bug: webrtc:9012
Change-Id: I028fe6b2a19e0d16b35956cc2df01dcf5bfa7979
Reviewed-on: https://webrtc-review.googlesource.com/63264
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22529}
2018-03-21 10:20:48 +00:00

581 lines
22 KiB
C++

/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/codecs/vp8/simulcast_rate_allocator.h"
#include <limits>
#include <memory>
#include <utility>
#include <vector>
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
using ::testing::_;
constexpr uint32_t kMinBitrateKbps = 50;
constexpr uint32_t kTargetBitrateKbps = 100;
constexpr uint32_t kMaxBitrateKbps = 1000;
constexpr uint32_t kFramerateFps = 5;
class MockTemporalLayers : public TemporalLayers {
public:
MOCK_METHOD1(UpdateLayerConfig, TemporalLayers::FrameConfig(uint32_t));
MOCK_METHOD2(OnRatesUpdated, void(const std::vector<uint32_t>&, int));
MOCK_METHOD1(UpdateConfiguration, bool(Vp8EncoderConfig*));
MOCK_METHOD4(PopulateCodecSpecific,
void(bool,
const TemporalLayers::FrameConfig&,
CodecSpecificInfoVP8*,
uint32_t));
MOCK_METHOD2(FrameEncoded, void(unsigned int, int));
MOCK_CONST_METHOD0(Tl0PicIdx, uint8_t());
MOCK_CONST_METHOD1(GetTemporalLayerId,
int(const TemporalLayers::FrameConfig&));
};
} // namespace
class SimulcastRateAllocatorTest : public ::testing::TestWithParam<bool> {
public:
SimulcastRateAllocatorTest() {
memset(&codec_, 0, sizeof(VideoCodec));
codec_.minBitrate = kMinBitrateKbps;
codec_.targetBitrate = kTargetBitrateKbps;
codec_.maxBitrate = kMaxBitrateKbps;
codec_.active = true;
CreateAllocator();
}
virtual ~SimulcastRateAllocatorTest() {}
template <size_t S>
void ExpectEqual(uint32_t (&expected)[S],
const std::vector<uint32_t>& actual) {
EXPECT_EQ(S, actual.size());
for (size_t i = 0; i < S; ++i)
EXPECT_EQ(expected[i], actual[i]) << "Mismatch at index " << i;
}
template <size_t S>
void ExpectEqual(uint32_t (&expected)[S], const BitrateAllocation& actual) {
// EXPECT_EQ(S, actual.size());
uint32_t sum = 0;
for (size_t i = 0; i < S; ++i) {
uint32_t layer_bitrate = actual.GetSpatialLayerSum(i);
if (layer_bitrate == 0) {
EXPECT_FALSE(actual.IsSpatialLayerUsed(i));
}
EXPECT_EQ(expected[i] * 1000U, layer_bitrate) << "Mismatch at index "
<< i;
sum += layer_bitrate;
}
EXPECT_EQ(sum, actual.get_sum_bps());
}
void CreateAllocator() {
allocator_.reset(new SimulcastRateAllocator(codec_));
}
void SetupCodecThreeSimulcastStreams(
const std::vector<bool>& active_streams) {
size_t num_streams = 3;
RTC_DCHECK_GE(active_streams.size(), num_streams);
SetupCodecTwoSimulcastStreams(active_streams);
codec_.numberOfSimulcastStreams = num_streams;
codec_.simulcastStream[2].minBitrate = 2000;
codec_.simulcastStream[2].targetBitrate = 3000;
codec_.simulcastStream[2].maxBitrate = 4000;
codec_.simulcastStream[2].active = active_streams[2];
}
void SetupCodecTwoSimulcastStreams(const std::vector<bool>& active_streams) {
size_t num_streams = 2;
RTC_DCHECK_GE(active_streams.size(), num_streams);
codec_.numberOfSimulcastStreams = num_streams;
codec_.maxBitrate = 0;
codec_.simulcastStream[0].minBitrate = 10;
codec_.simulcastStream[0].targetBitrate = 100;
codec_.simulcastStream[0].maxBitrate = 500;
codec_.simulcastStream[1].minBitrate = 50;
codec_.simulcastStream[1].targetBitrate = 500;
codec_.simulcastStream[1].maxBitrate = 1000;
for (size_t i = 0; i < num_streams; ++i) {
codec_.simulcastStream[i].active = active_streams[i];
}
}
BitrateAllocation GetAllocation(uint32_t target_bitrate) {
return allocator_->GetAllocation(target_bitrate * 1000U, kDefaultFrameRate);
}
protected:
static const int kDefaultFrameRate = 30;
VideoCodec codec_;
std::unique_ptr<SimulcastRateAllocator> allocator_;
};
TEST_F(SimulcastRateAllocatorTest, NoSimulcastBelowMin) {
uint32_t expected[] = {codec_.minBitrate};
codec_.active = true;
ExpectEqual(expected, GetAllocation(codec_.minBitrate - 1));
ExpectEqual(expected, GetAllocation(1));
ExpectEqual(expected, GetAllocation(0));
}
TEST_F(SimulcastRateAllocatorTest, NoSimulcastAboveMax) {
uint32_t expected[] = {codec_.maxBitrate};
codec_.active = true;
ExpectEqual(expected, GetAllocation(codec_.maxBitrate + 1));
ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}
TEST_F(SimulcastRateAllocatorTest, NoSimulcastNoMax) {
const uint32_t kMax = BitrateAllocation::kMaxBitrateBps / 1000;
codec_.active = true;
codec_.maxBitrate = 0;
CreateAllocator();
uint32_t expected[] = {kMax};
ExpectEqual(expected, GetAllocation(kMax));
}
TEST_F(SimulcastRateAllocatorTest, NoSimulcastWithinLimits) {
codec_.active = true;
for (uint32_t bitrate = codec_.minBitrate; bitrate <= codec_.maxBitrate;
++bitrate) {
uint32_t expected[] = {bitrate};
ExpectEqual(expected, GetAllocation(bitrate));
}
}
// Tests that when we aren't using simulcast and the codec is marked inactive no
// bitrate will be allocated.
TEST_F(SimulcastRateAllocatorTest, NoSimulcastInactive) {
codec_.active = false;
uint32_t expected[] = {0};
CreateAllocator();
ExpectEqual(expected, GetAllocation(kMinBitrateKbps - 10));
ExpectEqual(expected, GetAllocation(kTargetBitrateKbps));
ExpectEqual(expected, GetAllocation(kMaxBitrateKbps + 10));
}
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastBelowMin) {
// With simulcast, use the min bitrate from the ss spec instead of the global.
codec_.numberOfSimulcastStreams = 1;
const uint32_t kMin = codec_.minBitrate - 10;
codec_.simulcastStream[0].minBitrate = kMin;
codec_.simulcastStream[0].targetBitrate = kTargetBitrateKbps;
codec_.simulcastStream[0].active = true;
CreateAllocator();
uint32_t expected[] = {kMin};
ExpectEqual(expected, GetAllocation(kMin - 1));
ExpectEqual(expected, GetAllocation(1));
ExpectEqual(expected, GetAllocation(0));
}
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastAboveMax) {
codec_.numberOfSimulcastStreams = 1;
codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
const uint32_t kMax = codec_.simulcastStream[0].maxBitrate + 1000;
codec_.simulcastStream[0].maxBitrate = kMax;
codec_.simulcastStream[0].active = true;
CreateAllocator();
uint32_t expected[] = {kMax};
ExpectEqual(expected, GetAllocation(kMax));
ExpectEqual(expected, GetAllocation(kMax + 1));
ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) {
codec_.numberOfSimulcastStreams = 1;
codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
codec_.simulcastStream[0].targetBitrate = kTargetBitrateKbps;
codec_.simulcastStream[0].maxBitrate = kMaxBitrateKbps;
codec_.simulcastStream[0].active = true;
CreateAllocator();
for (uint32_t bitrate = kMinBitrateKbps; bitrate <= kMaxBitrateKbps;
++bitrate) {
uint32_t expected[] = {bitrate};
ExpectEqual(expected, GetAllocation(bitrate));
}
}
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastInactive) {
codec_.numberOfSimulcastStreams = 1;
codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
codec_.simulcastStream[0].targetBitrate = kTargetBitrateKbps;
codec_.simulcastStream[0].maxBitrate = kMaxBitrateKbps;
codec_.simulcastStream[0].active = false;
CreateAllocator();
uint32_t expected[] = {0};
ExpectEqual(expected, GetAllocation(kMinBitrateKbps - 10));
ExpectEqual(expected, GetAllocation(kTargetBitrateKbps));
ExpectEqual(expected, GetAllocation(kMaxBitrateKbps + 10));
}
TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
const std::vector<bool> active_streams(3, true);
SetupCodecThreeSimulcastStreams(active_streams);
CreateAllocator();
{
// Single stream, min bitrate.
const uint32_t bitrate = codec_.simulcastStream[0].minBitrate;
uint32_t expected[] = {bitrate, 0, 0};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Single stream at target bitrate.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate;
uint32_t expected[] = {bitrate, 0, 0};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Bitrate above target for first stream, but below min for the next one.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[1].minBitrate - 1;
uint32_t expected[] = {bitrate, 0, 0};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Just enough for two streams.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[1].minBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].minBitrate, 0};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Second stream maxed out, but not enough for third.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[1].maxBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].maxBitrate, 0};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// First two streams maxed out, but not enough for third. Nowhere to put
// remaining bits.
const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate +
codec_.simulcastStream[1].maxBitrate + 499;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].maxBitrate, 0};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Just enough for all three streams.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[1].targetBitrate +
codec_.simulcastStream[2].minBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].targetBitrate,
codec_.simulcastStream[2].minBitrate};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Third maxed out.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[1].targetBitrate +
codec_.simulcastStream[2].maxBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].targetBitrate,
codec_.simulcastStream[2].maxBitrate};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Enough to max out all streams which will allocate the target amount to
// the lower streams.
const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate +
codec_.simulcastStream[1].maxBitrate +
codec_.simulcastStream[2].maxBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].targetBitrate,
codec_.simulcastStream[2].maxBitrate};
ExpectEqual(expected, GetAllocation(bitrate));
}
}
// If three simulcast streams that are all inactive, none of them should be
// allocated bitrate.
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsInactive) {
const std::vector<bool> active_streams(3, false);
SetupCodecThreeSimulcastStreams(active_streams);
CreateAllocator();
// Just enough to allocate the min.
const uint32_t min_bitrate = codec_.simulcastStream[0].minBitrate +
codec_.simulcastStream[1].minBitrate +
codec_.simulcastStream[2].minBitrate;
// Enough bitrate to allocate target to all streams.
const uint32_t target_bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[1].targetBitrate +
codec_.simulcastStream[2].targetBitrate;
// Enough bitrate to allocate max to all streams.
const uint32_t max_bitrate = codec_.simulcastStream[0].maxBitrate +
codec_.simulcastStream[1].maxBitrate +
codec_.simulcastStream[2].maxBitrate;
uint32_t expected[] = {0, 0, 0};
ExpectEqual(expected, GetAllocation(0));
ExpectEqual(expected, GetAllocation(min_bitrate));
ExpectEqual(expected, GetAllocation(target_bitrate));
ExpectEqual(expected, GetAllocation(max_bitrate));
}
// If there are two simulcast streams, we expect the high active stream to be
// allocated as if it is a single active stream.
TEST_F(SimulcastRateAllocatorTest, TwoStreamsLowInactive) {
const std::vector<bool> active_streams({false, true});
SetupCodecTwoSimulcastStreams(active_streams);
CreateAllocator();
const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[1].minBitrate;
const uint32_t kActiveStreamTargetBitrate =
codec_.simulcastStream[1].targetBitrate;
const uint32_t kActiveStreamMaxBitrate = codec_.simulcastStream[1].maxBitrate;
{
// Expect that the stream is always allocated its min bitrate.
uint32_t expected[] = {0, kActiveStreamMinBitrate};
ExpectEqual(expected, GetAllocation(0));
ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate - 10));
ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate));
}
{
// The stream should be allocated its target bitrate.
uint32_t expected[] = {0, kActiveStreamTargetBitrate};
ExpectEqual(expected, GetAllocation(kActiveStreamTargetBitrate));
}
{
// The stream should be allocated its max if the target input is sufficient.
uint32_t expected[] = {0, kActiveStreamMaxBitrate};
ExpectEqual(expected, GetAllocation(kActiveStreamMaxBitrate));
ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}
}
// If there are two simulcast streams, we expect the low active stream to be
// allocated as if it is a single active stream.
TEST_F(SimulcastRateAllocatorTest, TwoStreamsHighInactive) {
const std::vector<bool> active_streams({true, false});
SetupCodecTwoSimulcastStreams(active_streams);
CreateAllocator();
const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[0].minBitrate;
const uint32_t kActiveStreamTargetBitrate =
codec_.simulcastStream[0].targetBitrate;
const uint32_t kActiveStreamMaxBitrate = codec_.simulcastStream[0].maxBitrate;
{
// Expect that the stream is always allocated its min bitrate.
uint32_t expected[] = {kActiveStreamMinBitrate, 0};
ExpectEqual(expected, GetAllocation(0));
ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate - 10));
ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate));
}
{
// The stream should be allocated its target bitrate.
uint32_t expected[] = {kActiveStreamTargetBitrate, 0};
ExpectEqual(expected, GetAllocation(kActiveStreamTargetBitrate));
}
{
// The stream should be allocated its max if the target input is sufficent.
uint32_t expected[] = {kActiveStreamMaxBitrate, 0};
ExpectEqual(expected, GetAllocation(kActiveStreamMaxBitrate));
ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}
}
// If there are three simulcast streams and the middle stream is inactive, the
// other two streams should be allocated bitrate the same as if they are two
// active simulcast streams.
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsMiddleInactive) {
const std::vector<bool> active_streams({true, false, true});
SetupCodecThreeSimulcastStreams(active_streams);
CreateAllocator();
{
const uint32_t kLowStreamMinBitrate = codec_.simulcastStream[0].minBitrate;
// The lowest stream should always be allocated its minimum bitrate.
uint32_t expected[] = {kLowStreamMinBitrate, 0, 0};
ExpectEqual(expected, GetAllocation(0));
ExpectEqual(expected, GetAllocation(kLowStreamMinBitrate - 10));
ExpectEqual(expected, GetAllocation(kLowStreamMinBitrate));
}
{
// The lowest stream gets its target bitrate.
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, 0, 0};
ExpectEqual(expected,
GetAllocation(codec_.simulcastStream[0].targetBitrate));
}
{
// The lowest stream gets its max bitrate, but not enough for the high
// stream.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[2].minBitrate - 1;
uint32_t expected[] = {codec_.simulcastStream[0].maxBitrate, 0, 0};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Both active streams get allocated target bitrate.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[2].targetBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, 0,
codec_.simulcastStream[2].targetBitrate};
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Lowest stream gets its target bitrate, high stream gets its max bitrate.
uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[2].maxBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, 0,
codec_.simulcastStream[2].maxBitrate};
ExpectEqual(expected, GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate + 10));
ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}
}
TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrateBps) {
MockTemporalLayers mock_layers;
allocator_.reset(new SimulcastRateAllocator(codec_));
EXPECT_CALL(mock_layers, OnRatesUpdated(_, _)).Times(0);
EXPECT_EQ(codec_.maxBitrate * 1000,
allocator_->GetPreferredBitrateBps(codec_.maxFramerate));
}
TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrateSimulcast) {
codec_.numberOfSimulcastStreams = 3;
codec_.maxBitrate = 999999;
codec_.simulcastStream[0].minBitrate = 10;
codec_.simulcastStream[0].targetBitrate = 100;
codec_.simulcastStream[0].active = true;
codec_.simulcastStream[0].maxBitrate = 500;
codec_.simulcastStream[1].minBitrate = 50;
codec_.simulcastStream[1].targetBitrate = 500;
codec_.simulcastStream[1].maxBitrate = 1000;
codec_.simulcastStream[1].active = true;
codec_.simulcastStream[2].minBitrate = 2000;
codec_.simulcastStream[2].targetBitrate = 3000;
codec_.simulcastStream[2].maxBitrate = 4000;
codec_.simulcastStream[2].active = true;
CreateAllocator();
uint32_t preferred_bitrate_kbps;
preferred_bitrate_kbps = codec_.simulcastStream[0].targetBitrate;
preferred_bitrate_kbps += codec_.simulcastStream[1].targetBitrate;
preferred_bitrate_kbps += codec_.simulcastStream[2].maxBitrate;
EXPECT_EQ(preferred_bitrate_kbps * 1000,
allocator_->GetPreferredBitrateBps(codec_.maxFramerate));
}
class ScreenshareRateAllocationTest : public SimulcastRateAllocatorTest {
public:
void SetupConferenceScreenshare(bool use_simulcast, bool active = true) {
codec_.mode = VideoCodecMode::kScreensharing;
codec_.minBitrate = kMinBitrateKbps;
codec_.maxBitrate = kMaxBitrateKbps;
if (use_simulcast) {
codec_.numberOfSimulcastStreams = 1;
codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
codec_.simulcastStream[0].targetBitrate = kTargetBitrateKbps;
codec_.simulcastStream[0].maxBitrate = kMaxBitrateKbps;
codec_.simulcastStream[0].numberOfTemporalLayers = 2;
codec_.simulcastStream[0].active = active;
} else {
codec_.numberOfSimulcastStreams = 0;
codec_.targetBitrate = kTargetBitrateKbps;
codec_.VP8()->numberOfTemporalLayers = 2;
codec_.active = active;
}
}
};
INSTANTIATE_TEST_CASE_P(ScreenshareTest,
ScreenshareRateAllocationTest,
::testing::Bool());
TEST_P(ScreenshareRateAllocationTest, BitrateBelowTl0) {
SetupConferenceScreenshare(GetParam());
CreateAllocator();
BitrateAllocation allocation =
allocator_->GetAllocation(kTargetBitrateKbps * 1000, kFramerateFps);
// All allocation should go in TL0.
EXPECT_EQ(kTargetBitrateKbps, allocation.get_sum_kbps());
EXPECT_EQ(kTargetBitrateKbps, allocation.GetBitrate(0, 0) / 1000);
}
TEST_P(ScreenshareRateAllocationTest, BitrateAboveTl0) {
SetupConferenceScreenshare(GetParam());
CreateAllocator();
uint32_t target_bitrate_kbps = (kTargetBitrateKbps + kMaxBitrateKbps) / 2;
BitrateAllocation allocation =
allocator_->GetAllocation(target_bitrate_kbps * 1000, kFramerateFps);
// Fill TL0, then put the rest in TL1.
EXPECT_EQ(target_bitrate_kbps, allocation.get_sum_kbps());
EXPECT_EQ(kTargetBitrateKbps, allocation.GetBitrate(0, 0) / 1000);
EXPECT_EQ(target_bitrate_kbps - kTargetBitrateKbps,
allocation.GetBitrate(0, 1) / 1000);
}
TEST_P(ScreenshareRateAllocationTest, BitrateAboveTl1) {
SetupConferenceScreenshare(GetParam());
CreateAllocator();
BitrateAllocation allocation =
allocator_->GetAllocation(kMaxBitrateKbps * 2000, kFramerateFps);
// Fill both TL0 and TL1, but no more.
EXPECT_EQ(kMaxBitrateKbps, allocation.get_sum_kbps());
EXPECT_EQ(kTargetBitrateKbps, allocation.GetBitrate(0, 0) / 1000);
EXPECT_EQ(kMaxBitrateKbps - kTargetBitrateKbps,
allocation.GetBitrate(0, 1) / 1000);
}
// This tests when the screenshare is inactive it should be allocated 0 bitrate
// for all layers.
TEST_P(ScreenshareRateAllocationTest, InactiveScreenshare) {
SetupConferenceScreenshare(GetParam(), false);
CreateAllocator();
// Enough bitrate for TL0 and TL1.
uint32_t target_bitrate_kbps = (kTargetBitrateKbps + kMaxBitrateKbps) / 2;
BitrateAllocation allocation =
allocator_->GetAllocation(target_bitrate_kbps * 1000, kFramerateFps);
EXPECT_EQ(0U, allocation.get_sum_kbps());
}
} // namespace webrtc