1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "call/bitrate_allocator.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <vector>
16*d9f75844SAndroid Build Coastguard Worker
17*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
18*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
19*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
20*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
21*d9f75844SAndroid Build Coastguard Worker
22*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
23*d9f75844SAndroid Build Coastguard Worker using ::testing::AllOf;
24*d9f75844SAndroid Build Coastguard Worker using ::testing::Field;
25*d9f75844SAndroid Build Coastguard Worker using ::testing::NiceMock;
26*d9f75844SAndroid Build Coastguard Worker
27*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
28*d9f75844SAndroid Build Coastguard Worker
29*d9f75844SAndroid Build Coastguard Worker namespace {
AllocationLimitsEq(uint32_t min_allocatable_rate_bps,uint32_t max_padding_rate_bps,uint32_t max_allocatable_rate_bps)30*d9f75844SAndroid Build Coastguard Worker auto AllocationLimitsEq(uint32_t min_allocatable_rate_bps,
31*d9f75844SAndroid Build Coastguard Worker uint32_t max_padding_rate_bps,
32*d9f75844SAndroid Build Coastguard Worker uint32_t max_allocatable_rate_bps) {
33*d9f75844SAndroid Build Coastguard Worker return AllOf(Field(&BitrateAllocationLimits::min_allocatable_rate,
34*d9f75844SAndroid Build Coastguard Worker DataRate::BitsPerSec(min_allocatable_rate_bps)),
35*d9f75844SAndroid Build Coastguard Worker Field(&BitrateAllocationLimits::max_allocatable_rate,
36*d9f75844SAndroid Build Coastguard Worker DataRate::BitsPerSec(max_allocatable_rate_bps)),
37*d9f75844SAndroid Build Coastguard Worker Field(&BitrateAllocationLimits::max_padding_rate,
38*d9f75844SAndroid Build Coastguard Worker DataRate::BitsPerSec(max_padding_rate_bps)));
39*d9f75844SAndroid Build Coastguard Worker }
40*d9f75844SAndroid Build Coastguard Worker
AllocationLimitsEq(uint32_t min_allocatable_rate_bps,uint32_t max_padding_rate_bps)41*d9f75844SAndroid Build Coastguard Worker auto AllocationLimitsEq(uint32_t min_allocatable_rate_bps,
42*d9f75844SAndroid Build Coastguard Worker uint32_t max_padding_rate_bps) {
43*d9f75844SAndroid Build Coastguard Worker return AllOf(Field(&BitrateAllocationLimits::min_allocatable_rate,
44*d9f75844SAndroid Build Coastguard Worker DataRate::BitsPerSec(min_allocatable_rate_bps)),
45*d9f75844SAndroid Build Coastguard Worker Field(&BitrateAllocationLimits::max_padding_rate,
46*d9f75844SAndroid Build Coastguard Worker DataRate::BitsPerSec(max_padding_rate_bps)));
47*d9f75844SAndroid Build Coastguard Worker }
48*d9f75844SAndroid Build Coastguard Worker
49*d9f75844SAndroid Build Coastguard Worker class MockLimitObserver : public BitrateAllocator::LimitObserver {
50*d9f75844SAndroid Build Coastguard Worker public:
51*d9f75844SAndroid Build Coastguard Worker MOCK_METHOD(void,
52*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged,
53*d9f75844SAndroid Build Coastguard Worker (BitrateAllocationLimits),
54*d9f75844SAndroid Build Coastguard Worker (override));
55*d9f75844SAndroid Build Coastguard Worker };
56*d9f75844SAndroid Build Coastguard Worker
57*d9f75844SAndroid Build Coastguard Worker class TestBitrateObserver : public BitrateAllocatorObserver {
58*d9f75844SAndroid Build Coastguard Worker public:
TestBitrateObserver()59*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver()
60*d9f75844SAndroid Build Coastguard Worker : last_bitrate_bps_(0),
61*d9f75844SAndroid Build Coastguard Worker last_fraction_loss_(0),
62*d9f75844SAndroid Build Coastguard Worker last_rtt_ms_(0),
63*d9f75844SAndroid Build Coastguard Worker last_probing_interval_ms_(0),
64*d9f75844SAndroid Build Coastguard Worker protection_ratio_(0.0) {}
65*d9f75844SAndroid Build Coastguard Worker
SetBitrateProtectionRatio(double protection_ratio)66*d9f75844SAndroid Build Coastguard Worker void SetBitrateProtectionRatio(double protection_ratio) {
67*d9f75844SAndroid Build Coastguard Worker protection_ratio_ = protection_ratio;
68*d9f75844SAndroid Build Coastguard Worker }
69*d9f75844SAndroid Build Coastguard Worker
OnBitrateUpdated(BitrateAllocationUpdate update)70*d9f75844SAndroid Build Coastguard Worker uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) override {
71*d9f75844SAndroid Build Coastguard Worker last_bitrate_bps_ = update.target_bitrate.bps();
72*d9f75844SAndroid Build Coastguard Worker last_fraction_loss_ =
73*d9f75844SAndroid Build Coastguard Worker rtc::dchecked_cast<uint8_t>(update.packet_loss_ratio * 256);
74*d9f75844SAndroid Build Coastguard Worker last_rtt_ms_ = update.round_trip_time.ms();
75*d9f75844SAndroid Build Coastguard Worker last_probing_interval_ms_ = update.bwe_period.ms();
76*d9f75844SAndroid Build Coastguard Worker return update.target_bitrate.bps() * protection_ratio_;
77*d9f75844SAndroid Build Coastguard Worker }
78*d9f75844SAndroid Build Coastguard Worker uint32_t last_bitrate_bps_;
79*d9f75844SAndroid Build Coastguard Worker uint8_t last_fraction_loss_;
80*d9f75844SAndroid Build Coastguard Worker int64_t last_rtt_ms_;
81*d9f75844SAndroid Build Coastguard Worker int last_probing_interval_ms_;
82*d9f75844SAndroid Build Coastguard Worker double protection_ratio_;
83*d9f75844SAndroid Build Coastguard Worker };
84*d9f75844SAndroid Build Coastguard Worker
85*d9f75844SAndroid Build Coastguard Worker constexpr int64_t kDefaultProbingIntervalMs = 3000;
86*d9f75844SAndroid Build Coastguard Worker const double kDefaultBitratePriority = 1.0;
87*d9f75844SAndroid Build Coastguard Worker
CreateTargetRateMessage(uint32_t target_bitrate_bps,uint8_t fraction_loss,int64_t rtt_ms,int64_t bwe_period_ms)88*d9f75844SAndroid Build Coastguard Worker TargetTransferRate CreateTargetRateMessage(uint32_t target_bitrate_bps,
89*d9f75844SAndroid Build Coastguard Worker uint8_t fraction_loss,
90*d9f75844SAndroid Build Coastguard Worker int64_t rtt_ms,
91*d9f75844SAndroid Build Coastguard Worker int64_t bwe_period_ms) {
92*d9f75844SAndroid Build Coastguard Worker TargetTransferRate msg;
93*d9f75844SAndroid Build Coastguard Worker // The timestamp is just for log output, keeping it fixed just means fewer log
94*d9f75844SAndroid Build Coastguard Worker // messages in the test.
95*d9f75844SAndroid Build Coastguard Worker msg.at_time = Timestamp::Seconds(10000);
96*d9f75844SAndroid Build Coastguard Worker msg.target_rate = DataRate::BitsPerSec(target_bitrate_bps);
97*d9f75844SAndroid Build Coastguard Worker msg.stable_target_rate = msg.target_rate;
98*d9f75844SAndroid Build Coastguard Worker msg.network_estimate.bandwidth = msg.target_rate;
99*d9f75844SAndroid Build Coastguard Worker msg.network_estimate.loss_rate_ratio = fraction_loss / 255.0;
100*d9f75844SAndroid Build Coastguard Worker msg.network_estimate.round_trip_time = TimeDelta::Millis(rtt_ms);
101*d9f75844SAndroid Build Coastguard Worker msg.network_estimate.bwe_period = TimeDelta::Millis(bwe_period_ms);
102*d9f75844SAndroid Build Coastguard Worker return msg;
103*d9f75844SAndroid Build Coastguard Worker }
104*d9f75844SAndroid Build Coastguard Worker } // namespace
105*d9f75844SAndroid Build Coastguard Worker
106*d9f75844SAndroid Build Coastguard Worker class BitrateAllocatorTest : public ::testing::Test {
107*d9f75844SAndroid Build Coastguard Worker protected:
BitrateAllocatorTest()108*d9f75844SAndroid Build Coastguard Worker BitrateAllocatorTest() : allocator_(new BitrateAllocator(&limit_observer_)) {
109*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
110*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000u, 0, 0, kDefaultProbingIntervalMs));
111*d9f75844SAndroid Build Coastguard Worker }
~BitrateAllocatorTest()112*d9f75844SAndroid Build Coastguard Worker ~BitrateAllocatorTest() {}
AddObserver(BitrateAllocatorObserver * observer,uint32_t min_bitrate_bps,uint32_t max_bitrate_bps,uint32_t pad_up_bitrate_bps,bool enforce_min_bitrate,double bitrate_priority)113*d9f75844SAndroid Build Coastguard Worker void AddObserver(BitrateAllocatorObserver* observer,
114*d9f75844SAndroid Build Coastguard Worker uint32_t min_bitrate_bps,
115*d9f75844SAndroid Build Coastguard Worker uint32_t max_bitrate_bps,
116*d9f75844SAndroid Build Coastguard Worker uint32_t pad_up_bitrate_bps,
117*d9f75844SAndroid Build Coastguard Worker bool enforce_min_bitrate,
118*d9f75844SAndroid Build Coastguard Worker double bitrate_priority) {
119*d9f75844SAndroid Build Coastguard Worker allocator_->AddObserver(
120*d9f75844SAndroid Build Coastguard Worker observer,
121*d9f75844SAndroid Build Coastguard Worker {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps,
122*d9f75844SAndroid Build Coastguard Worker /* priority_bitrate */ 0, enforce_min_bitrate, bitrate_priority});
123*d9f75844SAndroid Build Coastguard Worker }
DefaultConfig() const124*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig DefaultConfig() const {
125*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig default_config;
126*d9f75844SAndroid Build Coastguard Worker default_config.min_bitrate_bps = 0;
127*d9f75844SAndroid Build Coastguard Worker default_config.max_bitrate_bps = 1500000;
128*d9f75844SAndroid Build Coastguard Worker default_config.pad_up_bitrate_bps = 0;
129*d9f75844SAndroid Build Coastguard Worker default_config.priority_bitrate_bps = 0;
130*d9f75844SAndroid Build Coastguard Worker default_config.enforce_min_bitrate = true;
131*d9f75844SAndroid Build Coastguard Worker default_config.bitrate_priority = kDefaultBitratePriority;
132*d9f75844SAndroid Build Coastguard Worker return default_config;
133*d9f75844SAndroid Build Coastguard Worker }
134*d9f75844SAndroid Build Coastguard Worker
135*d9f75844SAndroid Build Coastguard Worker NiceMock<MockLimitObserver> limit_observer_;
136*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<BitrateAllocator> allocator_;
137*d9f75844SAndroid Build Coastguard Worker };
138*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,RespectsPriorityBitrate)139*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, RespectsPriorityBitrate) {
140*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver stream_a;
141*d9f75844SAndroid Build Coastguard Worker auto config_a = DefaultConfig();
142*d9f75844SAndroid Build Coastguard Worker config_a.min_bitrate_bps = 100000;
143*d9f75844SAndroid Build Coastguard Worker config_a.priority_bitrate_bps = 0;
144*d9f75844SAndroid Build Coastguard Worker allocator_->AddObserver(&stream_a, config_a);
145*d9f75844SAndroid Build Coastguard Worker
146*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver stream_b;
147*d9f75844SAndroid Build Coastguard Worker auto config_b = DefaultConfig();
148*d9f75844SAndroid Build Coastguard Worker config_b.min_bitrate_bps = 100000;
149*d9f75844SAndroid Build Coastguard Worker config_b.max_bitrate_bps = 300000;
150*d9f75844SAndroid Build Coastguard Worker config_b.priority_bitrate_bps = 300000;
151*d9f75844SAndroid Build Coastguard Worker allocator_->AddObserver(&stream_b, config_b);
152*d9f75844SAndroid Build Coastguard Worker
153*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
154*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(100000, 0, 0, 0));
155*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
156*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_b.last_bitrate_bps_, 100000u);
157*d9f75844SAndroid Build Coastguard Worker
158*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
159*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(200000, 0, 0, 0));
160*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
161*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_b.last_bitrate_bps_, 100000u);
162*d9f75844SAndroid Build Coastguard Worker
163*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
164*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000, 0, 0, 0));
165*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
166*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_b.last_bitrate_bps_, 200000u);
167*d9f75844SAndroid Build Coastguard Worker
168*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
169*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(400000, 0, 0, 0));
170*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
171*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_b.last_bitrate_bps_, 300000u);
172*d9f75844SAndroid Build Coastguard Worker
173*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
174*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(800000, 0, 0, 0));
175*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_a.last_bitrate_bps_, 500000u);
176*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stream_b.last_bitrate_bps_, 300000u);
177*d9f75844SAndroid Build Coastguard Worker }
178*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,UpdatingBitrateObserver)179*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, UpdatingBitrateObserver) {
180*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer;
181*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinSendBitrateBps = 100000;
182*d9f75844SAndroid Build Coastguard Worker const uint32_t kPadUpToBitrateBps = 50000;
183*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxBitrateBps = 1500000;
184*d9f75844SAndroid Build Coastguard Worker
185*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
186*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(
187*d9f75844SAndroid Build Coastguard Worker kMinSendBitrateBps, kPadUpToBitrateBps, kMaxBitrateBps)));
188*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
189*d9f75844SAndroid Build Coastguard Worker kPadUpToBitrateBps, true, kDefaultBitratePriority);
190*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
191*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
192*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(200000, 0, 0, kDefaultProbingIntervalMs));
193*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer));
194*d9f75844SAndroid Build Coastguard Worker
195*d9f75844SAndroid Build Coastguard Worker // TODO(pbos): Expect capping to 1.5M instead of 3M when not boosting the max
196*d9f75844SAndroid Build Coastguard Worker // bitrate for FEC/retransmissions (see todo in BitrateAllocator).
197*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
198*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(4000000, 0, 0, kDefaultProbingIntervalMs));
199*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3000000, allocator_->GetStartBitrate(&bitrate_observer));
200*d9f75844SAndroid Build Coastguard Worker
201*d9f75844SAndroid Build Coastguard Worker // Expect `max_padding_bitrate_bps` to change to 0 if the observer is updated.
202*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
203*d9f75844SAndroid Build Coastguard Worker AllocationLimitsEq(kMinSendBitrateBps, 0)));
204*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer, kMinSendBitrateBps, 4000000, 0, true,
205*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
206*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
207*d9f75844SAndroid Build Coastguard Worker AllocationLimitsEq(kMinSendBitrateBps, 0)));
208*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(4000000, allocator_->GetStartBitrate(&bitrate_observer));
209*d9f75844SAndroid Build Coastguard Worker
210*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps, 0, true,
211*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
212*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3000000, allocator_->GetStartBitrate(&bitrate_observer));
213*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3000000u, bitrate_observer.last_bitrate_bps_);
214*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
215*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(kMaxBitrateBps, 0, 0, kDefaultProbingIntervalMs));
216*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1500000u, bitrate_observer.last_bitrate_bps_);
217*d9f75844SAndroid Build Coastguard Worker }
218*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,TwoBitrateObserversOneRtcpObserver)219*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, TwoBitrateObserversOneRtcpObserver) {
220*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_1;
221*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_2;
222*d9f75844SAndroid Build Coastguard Worker const uint32_t kObs1StartBitrateBps = 100000;
223*d9f75844SAndroid Build Coastguard Worker const uint32_t kObs2StartBitrateBps = 200000;
224*d9f75844SAndroid Build Coastguard Worker const uint32_t kObs1MaxBitrateBps = 300000;
225*d9f75844SAndroid Build Coastguard Worker const uint32_t kObs2MaxBitrateBps = 300000;
226*d9f75844SAndroid Build Coastguard Worker
227*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
228*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(
229*d9f75844SAndroid Build Coastguard Worker kObs1StartBitrateBps, 0, kObs1MaxBitrateBps)));
230*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_1, kObs1StartBitrateBps, kObs1MaxBitrateBps, 0,
231*d9f75844SAndroid Build Coastguard Worker true, kDefaultBitratePriority);
232*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(kObs1MaxBitrateBps),
233*d9f75844SAndroid Build Coastguard Worker allocator_->GetStartBitrate(&bitrate_observer_1));
234*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
235*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(
236*d9f75844SAndroid Build Coastguard Worker kObs1StartBitrateBps + kObs2StartBitrateBps, 0,
237*d9f75844SAndroid Build Coastguard Worker kObs1MaxBitrateBps + kObs2MaxBitrateBps)));
238*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_2, kObs2StartBitrateBps, kObs2MaxBitrateBps, 0,
239*d9f75844SAndroid Build Coastguard Worker true, kDefaultBitratePriority);
240*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(kObs2StartBitrateBps),
241*d9f75844SAndroid Build Coastguard Worker allocator_->GetStartBitrate(&bitrate_observer_2));
242*d9f75844SAndroid Build Coastguard Worker
243*d9f75844SAndroid Build Coastguard Worker // Test too low start bitrate, hence lower than sum of min. Min bitrates
244*d9f75844SAndroid Build Coastguard Worker // will
245*d9f75844SAndroid Build Coastguard Worker // be allocated to all observers.
246*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
247*d9f75844SAndroid Build Coastguard Worker kObs2StartBitrateBps, 0, 50, kDefaultProbingIntervalMs));
248*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
249*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
250*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(50, bitrate_observer_1.last_rtt_ms_);
251*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);
252*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
253*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(50, bitrate_observer_2.last_rtt_ms_);
254*d9f75844SAndroid Build Coastguard Worker
255*d9f75844SAndroid Build Coastguard Worker // Test a bitrate which should be distributed equally.
256*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
257*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(500000, 0, 50, kDefaultProbingIntervalMs));
258*d9f75844SAndroid Build Coastguard Worker const uint32_t kBitrateToShare =
259*d9f75844SAndroid Build Coastguard Worker 500000 - kObs2StartBitrateBps - kObs1StartBitrateBps;
260*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u + kBitrateToShare / 2,
261*d9f75844SAndroid Build Coastguard Worker bitrate_observer_1.last_bitrate_bps_);
262*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u + kBitrateToShare / 2,
263*d9f75844SAndroid Build Coastguard Worker bitrate_observer_2.last_bitrate_bps_);
264*d9f75844SAndroid Build Coastguard Worker
265*d9f75844SAndroid Build Coastguard Worker // Limited by 2x max bitrates since we leave room for FEC and
266*d9f75844SAndroid Build Coastguard Worker // retransmissions.
267*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
268*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(1500000, 0, 50, kDefaultProbingIntervalMs));
269*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(600000u, bitrate_observer_1.last_bitrate_bps_);
270*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(600000u, bitrate_observer_2.last_bitrate_bps_);
271*d9f75844SAndroid Build Coastguard Worker
272*d9f75844SAndroid Build Coastguard Worker // Verify that if the bandwidth estimate is set to zero, the allocated
273*d9f75844SAndroid Build Coastguard Worker // rate is
274*d9f75844SAndroid Build Coastguard Worker // zero.
275*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
276*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(0, 0, 50, kDefaultProbingIntervalMs));
277*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
278*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
279*d9f75844SAndroid Build Coastguard Worker }
280*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,RemoveObserverTriggersLimitObserver)281*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, RemoveObserverTriggersLimitObserver) {
282*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer;
283*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinSendBitrateBps = 100000;
284*d9f75844SAndroid Build Coastguard Worker const uint32_t kPadUpToBitrateBps = 50000;
285*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxBitrateBps = 1500000;
286*d9f75844SAndroid Build Coastguard Worker
287*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
288*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(
289*d9f75844SAndroid Build Coastguard Worker kMinSendBitrateBps, kPadUpToBitrateBps, kMaxBitrateBps)));
290*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
291*d9f75844SAndroid Build Coastguard Worker kPadUpToBitrateBps, true, kDefaultBitratePriority);
292*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
293*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(0, 0)));
294*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer);
295*d9f75844SAndroid Build Coastguard Worker }
296*d9f75844SAndroid Build Coastguard Worker
297*d9f75844SAndroid Build Coastguard Worker class BitrateAllocatorTestNoEnforceMin : public ::testing::Test {
298*d9f75844SAndroid Build Coastguard Worker protected:
BitrateAllocatorTestNoEnforceMin()299*d9f75844SAndroid Build Coastguard Worker BitrateAllocatorTestNoEnforceMin()
300*d9f75844SAndroid Build Coastguard Worker : allocator_(new BitrateAllocator(&limit_observer_)) {
301*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
302*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000u, 0, 0, kDefaultProbingIntervalMs));
303*d9f75844SAndroid Build Coastguard Worker }
~BitrateAllocatorTestNoEnforceMin()304*d9f75844SAndroid Build Coastguard Worker ~BitrateAllocatorTestNoEnforceMin() {}
AddObserver(BitrateAllocatorObserver * observer,uint32_t min_bitrate_bps,uint32_t max_bitrate_bps,uint32_t pad_up_bitrate_bps,bool enforce_min_bitrate,absl::string_view track_id,double bitrate_priority)305*d9f75844SAndroid Build Coastguard Worker void AddObserver(BitrateAllocatorObserver* observer,
306*d9f75844SAndroid Build Coastguard Worker uint32_t min_bitrate_bps,
307*d9f75844SAndroid Build Coastguard Worker uint32_t max_bitrate_bps,
308*d9f75844SAndroid Build Coastguard Worker uint32_t pad_up_bitrate_bps,
309*d9f75844SAndroid Build Coastguard Worker bool enforce_min_bitrate,
310*d9f75844SAndroid Build Coastguard Worker absl::string_view track_id,
311*d9f75844SAndroid Build Coastguard Worker double bitrate_priority) {
312*d9f75844SAndroid Build Coastguard Worker allocator_->AddObserver(
313*d9f75844SAndroid Build Coastguard Worker observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps, 0,
314*d9f75844SAndroid Build Coastguard Worker enforce_min_bitrate, bitrate_priority});
315*d9f75844SAndroid Build Coastguard Worker }
316*d9f75844SAndroid Build Coastguard Worker NiceMock<MockLimitObserver> limit_observer_;
317*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<BitrateAllocator> allocator_;
318*d9f75844SAndroid Build Coastguard Worker };
319*d9f75844SAndroid Build Coastguard Worker
320*d9f75844SAndroid Build Coastguard Worker // The following three tests verify enforcing a minimum bitrate works as
321*d9f75844SAndroid Build Coastguard Worker // intended.
TEST_F(BitrateAllocatorTestNoEnforceMin,OneBitrateObserver)322*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTestNoEnforceMin, OneBitrateObserver) {
323*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_1;
324*d9f75844SAndroid Build Coastguard Worker // Expect OnAllocationLimitsChanged with `min_send_bitrate_bps` = 0 since
325*d9f75844SAndroid Build Coastguard Worker // AddObserver is called with `enforce_min_bitrate` = false.
326*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
327*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(0, 0)));
328*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
329*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(0, 120000)));
330*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_1, 100000, 400000, 0, false, "",
331*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
332*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
333*d9f75844SAndroid Build Coastguard Worker
334*d9f75844SAndroid Build Coastguard Worker // High BWE.
335*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
336*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(150000, 0, 0, kDefaultProbingIntervalMs));
337*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_bps_);
338*d9f75844SAndroid Build Coastguard Worker
339*d9f75844SAndroid Build Coastguard Worker // Low BWE.
340*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
341*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(10000, 0, 0, kDefaultProbingIntervalMs));
342*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
343*d9f75844SAndroid Build Coastguard Worker
344*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
345*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(0, 0)));
346*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_1);
347*d9f75844SAndroid Build Coastguard Worker }
348*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTestNoEnforceMin,ThreeBitrateObservers)349*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTestNoEnforceMin, ThreeBitrateObservers) {
350*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_1;
351*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_2;
352*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_3;
353*d9f75844SAndroid Build Coastguard Worker // Set up the observers with min bitrates at 100000, 200000, and 300000.
354*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_1, 100000, 400000, 0, false, "",
355*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
356*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
357*d9f75844SAndroid Build Coastguard Worker
358*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_2, 200000, 400000, 0, false, "",
359*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
360*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
361*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
362*d9f75844SAndroid Build Coastguard Worker
363*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_3, 300000, 400000, 0, false, "",
364*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
365*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, allocator_->GetStartBitrate(&bitrate_observer_3));
366*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
367*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);
368*d9f75844SAndroid Build Coastguard Worker
369*d9f75844SAndroid Build Coastguard Worker // High BWE. Make sure the controllers get a fair share of the surplus (i.e.,
370*d9f75844SAndroid Build Coastguard Worker // what is left after each controller gets its min rate).
371*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
372*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(690000, 0, 0, kDefaultProbingIntervalMs));
373*d9f75844SAndroid Build Coastguard Worker // Verify that each observer gets its min rate (sum of min rates is 600000),
374*d9f75844SAndroid Build Coastguard Worker // and that the remaining 90000 is divided equally among the three.
375*d9f75844SAndroid Build Coastguard Worker uint32_t bitrate_to_share = 690000u - 100000u - 200000u - 300000u;
376*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u + bitrate_to_share / 3,
377*d9f75844SAndroid Build Coastguard Worker bitrate_observer_1.last_bitrate_bps_);
378*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u + bitrate_to_share / 3,
379*d9f75844SAndroid Build Coastguard Worker bitrate_observer_2.last_bitrate_bps_);
380*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000u + bitrate_to_share / 3,
381*d9f75844SAndroid Build Coastguard Worker bitrate_observer_3.last_bitrate_bps_);
382*d9f75844SAndroid Build Coastguard Worker
383*d9f75844SAndroid Build Coastguard Worker // BWE below the sum of observer's min bitrate.
384*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
385*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000, 0, 0, kDefaultProbingIntervalMs));
386*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_); // Min bitrate.
387*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_); // Min bitrate.
388*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_); // Nothing.
389*d9f75844SAndroid Build Coastguard Worker
390*d9f75844SAndroid Build Coastguard Worker // Increased BWE, but still below the sum of configured min bitrates for all
391*d9f75844SAndroid Build Coastguard Worker // observers and too little for observer 3. 1 and 2 will share the rest.
392*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
393*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(500000, 0, 0, kDefaultProbingIntervalMs));
394*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u, bitrate_observer_1.last_bitrate_bps_); // Min + split.
395*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_bps_); // Min + split.
396*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_); // Nothing.
397*d9f75844SAndroid Build Coastguard Worker
398*d9f75844SAndroid Build Coastguard Worker // Below min for all.
399*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
400*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(10000, 0, 0, kDefaultProbingIntervalMs));
401*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
402*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
403*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_);
404*d9f75844SAndroid Build Coastguard Worker
405*d9f75844SAndroid Build Coastguard Worker // Verify that zero estimated bandwidth, means that that all gets zero,
406*d9f75844SAndroid Build Coastguard Worker // regardless of set min bitrate.
407*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
408*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(0, 0, 0, kDefaultProbingIntervalMs));
409*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
410*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
411*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_);
412*d9f75844SAndroid Build Coastguard Worker
413*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_1);
414*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_2);
415*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_3);
416*d9f75844SAndroid Build Coastguard Worker }
417*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTestNoEnforceMin,OneBitrateObserverWithPacketLoss)418*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTestNoEnforceMin, OneBitrateObserverWithPacketLoss) {
419*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinBitrateBps = 100000;
420*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxBitrateBps = 400000;
421*d9f75844SAndroid Build Coastguard Worker // Hysteresis adds another 10% or 20kbps to min bitrate.
422*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinStartBitrateBps =
423*d9f75844SAndroid Build Coastguard Worker kMinBitrateBps + std::max(20000u, kMinBitrateBps / 10);
424*d9f75844SAndroid Build Coastguard Worker
425*d9f75844SAndroid Build Coastguard Worker // Expect OnAllocationLimitsChanged with `min_send_bitrate_bps` = 0 since
426*d9f75844SAndroid Build Coastguard Worker // AddObserver is called with `enforce_min_bitrate` = false.
427*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer;
428*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
429*d9f75844SAndroid Build Coastguard Worker AllocationLimitsEq(0, 0, kMaxBitrateBps)));
430*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer, kMinBitrateBps, kMaxBitrateBps, 0, false, "",
431*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
432*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
433*d9f75844SAndroid Build Coastguard Worker
434*d9f75844SAndroid Build Coastguard Worker // High BWE.
435*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
436*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(150000, 0, 0, kDefaultProbingIntervalMs));
437*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(150000u, bitrate_observer.last_bitrate_bps_);
438*d9f75844SAndroid Build Coastguard Worker
439*d9f75844SAndroid Build Coastguard Worker // Add loss and use a part of the bitrate for protection.
440*d9f75844SAndroid Build Coastguard Worker const double kProtectionRatio = 0.4;
441*d9f75844SAndroid Build Coastguard Worker const uint8_t fraction_loss = kProtectionRatio * 256;
442*d9f75844SAndroid Build Coastguard Worker bitrate_observer.SetBitrateProtectionRatio(kProtectionRatio);
443*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
444*d9f75844SAndroid Build Coastguard Worker 200000, 0, fraction_loss, kDefaultProbingIntervalMs));
445*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u, bitrate_observer.last_bitrate_bps_);
446*d9f75844SAndroid Build Coastguard Worker
447*d9f75844SAndroid Build Coastguard Worker // Above the min threshold, but not enough given the protection used.
448*d9f75844SAndroid Build Coastguard Worker // Limits changed, as we will video is now off and we need to pad up to the
449*d9f75844SAndroid Build Coastguard Worker // start bitrate.
450*d9f75844SAndroid Build Coastguard Worker // Verify the hysteresis is added for the protection.
451*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinStartBitrateWithProtectionBps =
452*d9f75844SAndroid Build Coastguard Worker static_cast<uint32_t>(kMinStartBitrateBps * (1 + kProtectionRatio));
453*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
454*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(
455*d9f75844SAndroid Build Coastguard Worker 0, kMinStartBitrateWithProtectionBps, kMaxBitrateBps)));
456*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
457*d9f75844SAndroid Build Coastguard Worker kMinStartBitrateBps + 1000, 0, fraction_loss, kDefaultProbingIntervalMs));
458*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer.last_bitrate_bps_);
459*d9f75844SAndroid Build Coastguard Worker
460*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
461*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(kMinStartBitrateWithProtectionBps - 1000, 0,
462*d9f75844SAndroid Build Coastguard Worker fraction_loss, kDefaultProbingIntervalMs));
463*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer.last_bitrate_bps_);
464*d9f75844SAndroid Build Coastguard Worker
465*d9f75844SAndroid Build Coastguard Worker // Just enough to enable video again.
466*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
467*d9f75844SAndroid Build Coastguard Worker AllocationLimitsEq(0, 0, kMaxBitrateBps)));
468*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
469*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(kMinStartBitrateWithProtectionBps, 0,
470*d9f75844SAndroid Build Coastguard Worker fraction_loss, kDefaultProbingIntervalMs));
471*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMinStartBitrateWithProtectionBps,
472*d9f75844SAndroid Build Coastguard Worker bitrate_observer.last_bitrate_bps_);
473*d9f75844SAndroid Build Coastguard Worker
474*d9f75844SAndroid Build Coastguard Worker // Remove all protection and make sure video is not paused as earlier.
475*d9f75844SAndroid Build Coastguard Worker bitrate_observer.SetBitrateProtectionRatio(0.0);
476*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
477*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(kMinStartBitrateWithProtectionBps - 1000, 0, 0,
478*d9f75844SAndroid Build Coastguard Worker kDefaultProbingIntervalMs));
479*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMinStartBitrateWithProtectionBps - 1000,
480*d9f75844SAndroid Build Coastguard Worker bitrate_observer.last_bitrate_bps_);
481*d9f75844SAndroid Build Coastguard Worker
482*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
483*d9f75844SAndroid Build Coastguard Worker kMinStartBitrateBps, 0, 0, kDefaultProbingIntervalMs));
484*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMinStartBitrateBps, bitrate_observer.last_bitrate_bps_);
485*d9f75844SAndroid Build Coastguard Worker
486*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
487*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(0, 0, 0)));
488*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer);
489*d9f75844SAndroid Build Coastguard Worker }
490*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,TotalAllocationLimitsAreUnaffectedByProtectionRatio)491*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest,
492*d9f75844SAndroid Build Coastguard Worker TotalAllocationLimitsAreUnaffectedByProtectionRatio) {
493*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer;
494*d9f75844SAndroid Build Coastguard Worker
495*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinBitrateBps = 100000;
496*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxBitrateBps = 400000;
497*d9f75844SAndroid Build Coastguard Worker
498*d9f75844SAndroid Build Coastguard Worker // Register `bitrate_observer` and expect total allocation limits to change.
499*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(AllocationLimitsEq(
500*d9f75844SAndroid Build Coastguard Worker kMinBitrateBps, 0, kMaxBitrateBps)))
501*d9f75844SAndroid Build Coastguard Worker .Times(1);
502*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig allocation_config = DefaultConfig();
503*d9f75844SAndroid Build Coastguard Worker allocation_config.min_bitrate_bps = kMinBitrateBps;
504*d9f75844SAndroid Build Coastguard Worker allocation_config.max_bitrate_bps = kMaxBitrateBps;
505*d9f75844SAndroid Build Coastguard Worker allocator_->AddObserver(&bitrate_observer, allocation_config);
506*d9f75844SAndroid Build Coastguard Worker
507*d9f75844SAndroid Build Coastguard Worker // Observer uses 20% of it's allocated bitrate for protection.
508*d9f75844SAndroid Build Coastguard Worker bitrate_observer.SetBitrateProtectionRatio(/*protection_ratio=*/0.2);
509*d9f75844SAndroid Build Coastguard Worker // Total allocation limits are unaffected by the protection rate change.
510*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_)).Times(0);
511*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
512*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(200000u, 0, 100, kDefaultProbingIntervalMs));
513*d9f75844SAndroid Build Coastguard Worker
514*d9f75844SAndroid Build Coastguard Worker // Observer uses 0% of it's allocated bitrate for protection.
515*d9f75844SAndroid Build Coastguard Worker bitrate_observer.SetBitrateProtectionRatio(/*protection_ratio=*/0.0);
516*d9f75844SAndroid Build Coastguard Worker // Total allocation limits are unaffected by the protection rate change.
517*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_)).Times(0);
518*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
519*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(200000u, 0, 100, kDefaultProbingIntervalMs));
520*d9f75844SAndroid Build Coastguard Worker
521*d9f75844SAndroid Build Coastguard Worker // Observer again uses 20% of it's allocated bitrate for protection.
522*d9f75844SAndroid Build Coastguard Worker bitrate_observer.SetBitrateProtectionRatio(/*protection_ratio=*/0.2);
523*d9f75844SAndroid Build Coastguard Worker // Total allocation limits are unaffected by the protection rate change.
524*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_)).Times(0);
525*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
526*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(200000u, 0, 100, kDefaultProbingIntervalMs));
527*d9f75844SAndroid Build Coastguard Worker }
528*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTestNoEnforceMin,TwoBitrateObserverWithPacketLoss)529*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTestNoEnforceMin, TwoBitrateObserverWithPacketLoss) {
530*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_1;
531*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_2;
532*d9f75844SAndroid Build Coastguard Worker
533*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_1, 100000, 400000, 0, false, "",
534*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
535*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
536*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_2, 200000, 400000, 0, false, "",
537*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
538*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
539*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
540*d9f75844SAndroid Build Coastguard Worker
541*d9f75844SAndroid Build Coastguard Worker // Enough bitrate for both.
542*d9f75844SAndroid Build Coastguard Worker bitrate_observer_2.SetBitrateProtectionRatio(0.5);
543*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
544*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000, 0, 0, kDefaultProbingIntervalMs));
545*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
546*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);
547*d9f75844SAndroid Build Coastguard Worker
548*d9f75844SAndroid Build Coastguard Worker // Above min for observer 2, but too little given the protection used.
549*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
550*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(330000, 0, 0, kDefaultProbingIntervalMs));
551*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(330000u, bitrate_observer_1.last_bitrate_bps_);
552*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
553*d9f75844SAndroid Build Coastguard Worker
554*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
555*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(100000, 0, 0, kDefaultProbingIntervalMs));
556*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
557*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
558*d9f75844SAndroid Build Coastguard Worker
559*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
560*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(99999, 0, 0, kDefaultProbingIntervalMs));
561*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
562*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
563*d9f75844SAndroid Build Coastguard Worker
564*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
565*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(119000, 0, 0, kDefaultProbingIntervalMs));
566*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
567*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
568*d9f75844SAndroid Build Coastguard Worker
569*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
570*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(120000, 0, 0, kDefaultProbingIntervalMs));
571*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(120000u, bitrate_observer_1.last_bitrate_bps_);
572*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
573*d9f75844SAndroid Build Coastguard Worker
574*d9f75844SAndroid Build Coastguard Worker // Verify the protection is accounted for before resuming observer 2.
575*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
576*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(429000, 0, 0, kDefaultProbingIntervalMs));
577*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(400000u, bitrate_observer_1.last_bitrate_bps_);
578*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
579*d9f75844SAndroid Build Coastguard Worker
580*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
581*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(430000, 0, 0, kDefaultProbingIntervalMs));
582*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
583*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(330000u, bitrate_observer_2.last_bitrate_bps_);
584*d9f75844SAndroid Build Coastguard Worker
585*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_1);
586*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_2);
587*d9f75844SAndroid Build Coastguard Worker }
588*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,ThreeBitrateObserversLowBweEnforceMin)589*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, ThreeBitrateObserversLowBweEnforceMin) {
590*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_1;
591*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_2;
592*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_3;
593*d9f75844SAndroid Build Coastguard Worker
594*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_1, 100000, 400000, 0, true,
595*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
596*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
597*d9f75844SAndroid Build Coastguard Worker
598*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_2, 200000, 400000, 0, true,
599*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
600*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
601*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
602*d9f75844SAndroid Build Coastguard Worker
603*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_3, 300000, 400000, 0, true,
604*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
605*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_3));
606*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000, static_cast<int>(bitrate_observer_1.last_bitrate_bps_));
607*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000, static_cast<int>(bitrate_observer_2.last_bitrate_bps_));
608*d9f75844SAndroid Build Coastguard Worker
609*d9f75844SAndroid Build Coastguard Worker // Low BWE. Verify that all observers still get their respective min
610*d9f75844SAndroid Build Coastguard Worker // bitrate.
611*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
612*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(1000, 0, 0, kDefaultProbingIntervalMs));
613*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_); // Min cap.
614*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_); // Min cap.
615*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000u, bitrate_observer_3.last_bitrate_bps_); // Min cap.
616*d9f75844SAndroid Build Coastguard Worker
617*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_1);
618*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_2);
619*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&bitrate_observer_3);
620*d9f75844SAndroid Build Coastguard Worker }
621*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,AddObserverWhileNetworkDown)622*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
623*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_1;
624*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
625*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(50000, 0)));
626*d9f75844SAndroid Build Coastguard Worker
627*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_1, 50000, 400000, 0, true,
628*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
629*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
630*d9f75844SAndroid Build Coastguard Worker
631*d9f75844SAndroid Build Coastguard Worker // Set network down, ie, no available bitrate.
632*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
633*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(0, 0, 0, kDefaultProbingIntervalMs));
634*d9f75844SAndroid Build Coastguard Worker
635*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
636*d9f75844SAndroid Build Coastguard Worker
637*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver bitrate_observer_2;
638*d9f75844SAndroid Build Coastguard Worker // Adding an observer while the network is down should not affect the limits.
639*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(limit_observer_,
640*d9f75844SAndroid Build Coastguard Worker OnAllocationLimitsChanged(AllocationLimitsEq(50000 + 50000, 0)));
641*d9f75844SAndroid Build Coastguard Worker AddObserver(&bitrate_observer_2, 50000, 400000, 0, true,
642*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
643*d9f75844SAndroid Build Coastguard Worker
644*d9f75844SAndroid Build Coastguard Worker // Expect the start_bitrate to be set as if the network was still up but that
645*d9f75844SAndroid Build Coastguard Worker // the new observer have been notified that the network is down.
646*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000 / 2, allocator_->GetStartBitrate(&bitrate_observer_2));
647*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
648*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
649*d9f75844SAndroid Build Coastguard Worker
650*d9f75844SAndroid Build Coastguard Worker // Set network back up.
651*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
652*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(1500000, 0, 50, kDefaultProbingIntervalMs));
653*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(750000u, bitrate_observer_1.last_bitrate_bps_);
654*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(750000u, bitrate_observer_2.last_bitrate_bps_);
655*d9f75844SAndroid Build Coastguard Worker }
656*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,MixedEnforecedConfigs)657*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, MixedEnforecedConfigs) {
658*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver enforced_observer;
659*d9f75844SAndroid Build Coastguard Worker AddObserver(&enforced_observer, 6000, 30000, 0, true,
660*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
661*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(60000, allocator_->GetStartBitrate(&enforced_observer));
662*d9f75844SAndroid Build Coastguard Worker
663*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver not_enforced_observer;
664*d9f75844SAndroid Build Coastguard Worker AddObserver(¬_enforced_observer, 30000, 2500000, 0, false,
665*d9f75844SAndroid Build Coastguard Worker kDefaultBitratePriority);
666*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(270000, allocator_->GetStartBitrate(¬_enforced_observer));
667*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
668*d9f75844SAndroid Build Coastguard Worker
669*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
670*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(36000, 0, 50, kDefaultProbingIntervalMs));
671*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
672*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30000u, not_enforced_observer.last_bitrate_bps_);
673*d9f75844SAndroid Build Coastguard Worker
674*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
675*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(35000, 0, 50, kDefaultProbingIntervalMs));
676*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
677*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
678*d9f75844SAndroid Build Coastguard Worker
679*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
680*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(5000, 0, 50, kDefaultProbingIntervalMs));
681*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
682*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
683*d9f75844SAndroid Build Coastguard Worker
684*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
685*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(36000, 0, 50, kDefaultProbingIntervalMs));
686*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
687*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
688*d9f75844SAndroid Build Coastguard Worker
689*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
690*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(55000, 0, 50, kDefaultProbingIntervalMs));
691*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
692*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
693*d9f75844SAndroid Build Coastguard Worker
694*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
695*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(56000, 0, 50, kDefaultProbingIntervalMs));
696*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
697*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(50000u, not_enforced_observer.last_bitrate_bps_);
698*d9f75844SAndroid Build Coastguard Worker
699*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
700*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(56000, 0, 50, kDefaultProbingIntervalMs));
701*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(16000u, enforced_observer.last_bitrate_bps_);
702*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(40000u, not_enforced_observer.last_bitrate_bps_);
703*d9f75844SAndroid Build Coastguard Worker
704*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&enforced_observer);
705*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(¬_enforced_observer);
706*d9f75844SAndroid Build Coastguard Worker }
707*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,AvoidToggleAbsolute)708*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, AvoidToggleAbsolute) {
709*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer;
710*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer, 30000, 300000, 0, false, kDefaultBitratePriority);
711*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
712*d9f75844SAndroid Build Coastguard Worker
713*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
714*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(30000, 0, 50, kDefaultProbingIntervalMs));
715*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30000u, observer.last_bitrate_bps_);
716*d9f75844SAndroid Build Coastguard Worker
717*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
718*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(20000, 0, 50, kDefaultProbingIntervalMs));
719*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.last_bitrate_bps_);
720*d9f75844SAndroid Build Coastguard Worker
721*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
722*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(30000, 0, 50, kDefaultProbingIntervalMs));
723*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.last_bitrate_bps_);
724*d9f75844SAndroid Build Coastguard Worker
725*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
726*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(49000, 0, 50, kDefaultProbingIntervalMs));
727*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.last_bitrate_bps_);
728*d9f75844SAndroid Build Coastguard Worker
729*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
730*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(50000, 0, 50, kDefaultProbingIntervalMs));
731*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(50000u, observer.last_bitrate_bps_);
732*d9f75844SAndroid Build Coastguard Worker
733*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
734*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(30000, 0, 50, kDefaultProbingIntervalMs));
735*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30000u, observer.last_bitrate_bps_);
736*d9f75844SAndroid Build Coastguard Worker
737*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer);
738*d9f75844SAndroid Build Coastguard Worker }
739*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,AvoidTogglePercent)740*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, AvoidTogglePercent) {
741*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer;
742*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer, 300000, 600000, 0, false, kDefaultBitratePriority);
743*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
744*d9f75844SAndroid Build Coastguard Worker
745*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
746*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000, 0, 50, kDefaultProbingIntervalMs));
747*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000u, observer.last_bitrate_bps_);
748*d9f75844SAndroid Build Coastguard Worker
749*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
750*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(200000, 0, 50, kDefaultProbingIntervalMs));
751*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.last_bitrate_bps_);
752*d9f75844SAndroid Build Coastguard Worker
753*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
754*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000, 0, 50, kDefaultProbingIntervalMs));
755*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.last_bitrate_bps_);
756*d9f75844SAndroid Build Coastguard Worker
757*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
758*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(329000, 0, 50, kDefaultProbingIntervalMs));
759*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.last_bitrate_bps_);
760*d9f75844SAndroid Build Coastguard Worker
761*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
762*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(330000, 0, 50, kDefaultProbingIntervalMs));
763*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(330000u, observer.last_bitrate_bps_);
764*d9f75844SAndroid Build Coastguard Worker
765*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
766*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000, 0, 50, kDefaultProbingIntervalMs));
767*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000u, observer.last_bitrate_bps_);
768*d9f75844SAndroid Build Coastguard Worker
769*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer);
770*d9f75844SAndroid Build Coastguard Worker }
771*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,PassProbingInterval)772*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PassProbingInterval) {
773*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer;
774*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer, 300000, 600000, 0, false, kDefaultBitratePriority);
775*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
776*d9f75844SAndroid Build Coastguard Worker
777*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
778*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(300000, 0, 50, 5000));
779*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(5000, observer.last_probing_interval_ms_);
780*d9f75844SAndroid Build Coastguard Worker
781*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer);
782*d9f75844SAndroid Build Coastguard Worker }
783*d9f75844SAndroid Build Coastguard Worker
TEST_F(BitrateAllocatorTest,PriorityRateOneObserverBasic)784*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateOneObserverBasic) {
785*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer;
786*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinSendBitrateBps = 10;
787*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxSendBitrateBps = 60;
788*d9f75844SAndroid Build Coastguard Worker const uint32_t kNetworkBandwidthBps = 30;
789*d9f75844SAndroid Build Coastguard Worker
790*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true, 2.0);
791*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
792*d9f75844SAndroid Build Coastguard Worker kNetworkBandwidthBps, 0, 0, kDefaultProbingIntervalMs));
793*d9f75844SAndroid Build Coastguard Worker
794*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kNetworkBandwidthBps, observer.last_bitrate_bps_);
795*d9f75844SAndroid Build Coastguard Worker
796*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer);
797*d9f75844SAndroid Build Coastguard Worker }
798*d9f75844SAndroid Build Coastguard Worker
799*d9f75844SAndroid Build Coastguard Worker // Tests that two observers with the same bitrate priority are allocated
800*d9f75844SAndroid Build Coastguard Worker // their bitrate evenly.
TEST_F(BitrateAllocatorTest,PriorityRateTwoObserversBasic)801*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversBasic) {
802*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low_1;
803*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low_2;
804*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinSendBitrateBps = 10;
805*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxSendBitrateBps = 60;
806*d9f75844SAndroid Build Coastguard Worker const uint32_t kNetworkBandwidthBps = 60;
807*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low_1, kMinSendBitrateBps, kMaxSendBitrateBps, 0, false,
808*d9f75844SAndroid Build Coastguard Worker 2.0);
809*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low_2, kMinSendBitrateBps, kMaxSendBitrateBps, 0, false,
810*d9f75844SAndroid Build Coastguard Worker 2.0);
811*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
812*d9f75844SAndroid Build Coastguard Worker kNetworkBandwidthBps, 0, 0, kDefaultProbingIntervalMs));
813*d9f75844SAndroid Build Coastguard Worker
814*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kNetworkBandwidthBps / 2, observer_low_1.last_bitrate_bps_);
815*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kNetworkBandwidthBps / 2, observer_low_2.last_bitrate_bps_);
816*d9f75844SAndroid Build Coastguard Worker
817*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low_1);
818*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low_2);
819*d9f75844SAndroid Build Coastguard Worker }
820*d9f75844SAndroid Build Coastguard Worker
821*d9f75844SAndroid Build Coastguard Worker // Tests that there is no difference in functionality when the min bitrate is
822*d9f75844SAndroid Build Coastguard Worker // enforced.
TEST_F(BitrateAllocatorTest,PriorityRateTwoObserversBasicMinEnforced)823*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversBasicMinEnforced) {
824*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low_1;
825*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low_2;
826*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinSendBitrateBps = 0;
827*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxSendBitrateBps = 60;
828*d9f75844SAndroid Build Coastguard Worker const uint32_t kNetworkBandwidthBps = 60;
829*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low_1, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
830*d9f75844SAndroid Build Coastguard Worker 2.0);
831*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low_2, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
832*d9f75844SAndroid Build Coastguard Worker 2.0);
833*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
834*d9f75844SAndroid Build Coastguard Worker kNetworkBandwidthBps, 0, 0, kDefaultProbingIntervalMs));
835*d9f75844SAndroid Build Coastguard Worker
836*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kNetworkBandwidthBps / 2, observer_low_1.last_bitrate_bps_);
837*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kNetworkBandwidthBps / 2, observer_low_2.last_bitrate_bps_);
838*d9f75844SAndroid Build Coastguard Worker
839*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low_1);
840*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low_2);
841*d9f75844SAndroid Build Coastguard Worker }
842*d9f75844SAndroid Build Coastguard Worker
843*d9f75844SAndroid Build Coastguard Worker // Tests that if the available bandwidth is the sum of the max bitrate
844*d9f75844SAndroid Build Coastguard Worker // of all observers, they will be allocated their max.
TEST_F(BitrateAllocatorTest,PriorityRateTwoObserversBothAllocatedMax)845*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversBothAllocatedMax) {
846*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low;
847*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_mid;
848*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinSendBitrateBps = 0;
849*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxSendBitrateBps = 60;
850*d9f75844SAndroid Build Coastguard Worker const uint32_t kNetworkBandwidthBps = kMaxSendBitrateBps * 2;
851*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
852*d9f75844SAndroid Build Coastguard Worker 2.0);
853*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_mid, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
854*d9f75844SAndroid Build Coastguard Worker 4.0);
855*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
856*d9f75844SAndroid Build Coastguard Worker kNetworkBandwidthBps, 0, 0, kDefaultProbingIntervalMs));
857*d9f75844SAndroid Build Coastguard Worker
858*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxSendBitrateBps, observer_low.last_bitrate_bps_);
859*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxSendBitrateBps, observer_mid.last_bitrate_bps_);
860*d9f75844SAndroid Build Coastguard Worker
861*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low);
862*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_mid);
863*d9f75844SAndroid Build Coastguard Worker }
864*d9f75844SAndroid Build Coastguard Worker
865*d9f75844SAndroid Build Coastguard Worker // Tests that after a higher bitrate priority observer has been allocated its
866*d9f75844SAndroid Build Coastguard Worker // max bitrate the lower priority observer will then be allocated the remaining
867*d9f75844SAndroid Build Coastguard Worker // bitrate.
TEST_F(BitrateAllocatorTest,PriorityRateTwoObserversOneAllocatedToMax)868*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversOneAllocatedToMax) {
869*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low;
870*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_mid;
871*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low, 10, 50, 0, false, 2.0);
872*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_mid, 10, 50, 0, false, 4.0);
873*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
874*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(90, 0, 0, kDefaultProbingIntervalMs));
875*d9f75844SAndroid Build Coastguard Worker
876*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(40u, observer_low.last_bitrate_bps_);
877*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(50u, observer_mid.last_bitrate_bps_);
878*d9f75844SAndroid Build Coastguard Worker
879*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low);
880*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_mid);
881*d9f75844SAndroid Build Coastguard Worker }
882*d9f75844SAndroid Build Coastguard Worker
883*d9f75844SAndroid Build Coastguard Worker // Tests that three observers with three different bitrate priorities will all
884*d9f75844SAndroid Build Coastguard Worker // be allocated bitrate according to their relative bitrate priority.
TEST_F(BitrateAllocatorTest,PriorityRateThreeObserversAllocatedRelativeAmounts)885*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest,
886*d9f75844SAndroid Build Coastguard Worker PriorityRateThreeObserversAllocatedRelativeAmounts) {
887*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low;
888*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_mid;
889*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_high;
890*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxBitrate = 100;
891*d9f75844SAndroid Build Coastguard Worker // Not enough bandwidth to fill any observer's max bitrate.
892*d9f75844SAndroid Build Coastguard Worker const uint32_t kNetworkBandwidthBps = 70;
893*d9f75844SAndroid Build Coastguard Worker const double kLowBitratePriority = 2.0;
894*d9f75844SAndroid Build Coastguard Worker const double kMidBitratePriority = 4.0;
895*d9f75844SAndroid Build Coastguard Worker const double kHighBitratePriority = 8.0;
896*d9f75844SAndroid Build Coastguard Worker const double kTotalBitratePriority =
897*d9f75844SAndroid Build Coastguard Worker kLowBitratePriority + kMidBitratePriority + kHighBitratePriority;
898*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low, 0, kMaxBitrate, 0, false, kLowBitratePriority);
899*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_mid, 0, kMaxBitrate, 0, false, kMidBitratePriority);
900*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_high, 0, kMaxBitrate, 0, false, kHighBitratePriority);
901*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
902*d9f75844SAndroid Build Coastguard Worker kNetworkBandwidthBps, 0, 0, kDefaultProbingIntervalMs));
903*d9f75844SAndroid Build Coastguard Worker
904*d9f75844SAndroid Build Coastguard Worker const double kLowFractionAllocated =
905*d9f75844SAndroid Build Coastguard Worker kLowBitratePriority / kTotalBitratePriority;
906*d9f75844SAndroid Build Coastguard Worker const double kMidFractionAllocated =
907*d9f75844SAndroid Build Coastguard Worker kMidBitratePriority / kTotalBitratePriority;
908*d9f75844SAndroid Build Coastguard Worker const double kHighFractionAllocated =
909*d9f75844SAndroid Build Coastguard Worker kHighBitratePriority / kTotalBitratePriority;
910*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kLowFractionAllocated * kNetworkBandwidthBps,
911*d9f75844SAndroid Build Coastguard Worker observer_low.last_bitrate_bps_);
912*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMidFractionAllocated * kNetworkBandwidthBps,
913*d9f75844SAndroid Build Coastguard Worker observer_mid.last_bitrate_bps_);
914*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kHighFractionAllocated * kNetworkBandwidthBps,
915*d9f75844SAndroid Build Coastguard Worker observer_high.last_bitrate_bps_);
916*d9f75844SAndroid Build Coastguard Worker
917*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low);
918*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_mid);
919*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_high);
920*d9f75844SAndroid Build Coastguard Worker }
921*d9f75844SAndroid Build Coastguard Worker
922*d9f75844SAndroid Build Coastguard Worker // Tests that after the high priority observer has been allocated its maximum
923*d9f75844SAndroid Build Coastguard Worker // bitrate, the other two observers are still allocated bitrate according to
924*d9f75844SAndroid Build Coastguard Worker // their relative bitrate priority.
TEST_F(BitrateAllocatorTest,PriorityRateThreeObserversHighAllocatedToMax)925*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateThreeObserversHighAllocatedToMax) {
926*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low;
927*d9f75844SAndroid Build Coastguard Worker const double kLowBitratePriority = 2.0;
928*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_mid;
929*d9f75844SAndroid Build Coastguard Worker const double kMidBitratePriority = 4.0;
930*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_high;
931*d9f75844SAndroid Build Coastguard Worker const double kHighBitratePriority = 8.0;
932*d9f75844SAndroid Build Coastguard Worker
933*d9f75844SAndroid Build Coastguard Worker const uint32_t kAvailableBitrate = 90;
934*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxBitrate = 40;
935*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinBitrate = 10;
936*d9f75844SAndroid Build Coastguard Worker // Remaining bitrate after allocating to all mins and knowing that the high
937*d9f75844SAndroid Build Coastguard Worker // priority observer will have its max bitrate allocated.
938*d9f75844SAndroid Build Coastguard Worker const uint32_t kRemainingBitrate =
939*d9f75844SAndroid Build Coastguard Worker kAvailableBitrate - kMaxBitrate - (2 * kMinBitrate);
940*d9f75844SAndroid Build Coastguard Worker
941*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low, kMinBitrate, kMaxBitrate, 0, false,
942*d9f75844SAndroid Build Coastguard Worker kLowBitratePriority);
943*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_mid, kMinBitrate, kMaxBitrate, 0, false,
944*d9f75844SAndroid Build Coastguard Worker kMidBitratePriority);
945*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_high, kMinBitrate, kMaxBitrate, 0, false,
946*d9f75844SAndroid Build Coastguard Worker kHighBitratePriority);
947*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
948*d9f75844SAndroid Build Coastguard Worker kAvailableBitrate, 0, 0, kDefaultProbingIntervalMs));
949*d9f75844SAndroid Build Coastguard Worker
950*d9f75844SAndroid Build Coastguard Worker const double kLowFractionAllocated =
951*d9f75844SAndroid Build Coastguard Worker kLowBitratePriority / (kLowBitratePriority + kMidBitratePriority);
952*d9f75844SAndroid Build Coastguard Worker const double kMidFractionAllocated =
953*d9f75844SAndroid Build Coastguard Worker kMidBitratePriority / (kLowBitratePriority + kMidBitratePriority);
954*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMinBitrate + (kRemainingBitrate * kLowFractionAllocated),
955*d9f75844SAndroid Build Coastguard Worker observer_low.last_bitrate_bps_);
956*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMinBitrate + (kRemainingBitrate * kMidFractionAllocated),
957*d9f75844SAndroid Build Coastguard Worker observer_mid.last_bitrate_bps_);
958*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(40u, observer_high.last_bitrate_bps_);
959*d9f75844SAndroid Build Coastguard Worker
960*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low);
961*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_mid);
962*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_high);
963*d9f75844SAndroid Build Coastguard Worker }
964*d9f75844SAndroid Build Coastguard Worker
965*d9f75844SAndroid Build Coastguard Worker // Tests that after the low priority observer has been allocated its maximum
966*d9f75844SAndroid Build Coastguard Worker // bitrate, the other two observers are still allocated bitrate according to
967*d9f75844SAndroid Build Coastguard Worker // their relative bitrate priority.
TEST_F(BitrateAllocatorTest,PriorityRateThreeObserversLowAllocatedToMax)968*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateThreeObserversLowAllocatedToMax) {
969*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low;
970*d9f75844SAndroid Build Coastguard Worker const double kLowBitratePriority = 2.0;
971*d9f75844SAndroid Build Coastguard Worker const uint32_t kLowMaxBitrate = 10;
972*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_mid;
973*d9f75844SAndroid Build Coastguard Worker const double kMidBitratePriority = 4.0;
974*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_high;
975*d9f75844SAndroid Build Coastguard Worker const double kHighBitratePriority = 8.0;
976*d9f75844SAndroid Build Coastguard Worker
977*d9f75844SAndroid Build Coastguard Worker const uint32_t kMinBitrate = 0;
978*d9f75844SAndroid Build Coastguard Worker const uint32_t kMaxBitrate = 60;
979*d9f75844SAndroid Build Coastguard Worker const uint32_t kAvailableBitrate = 100;
980*d9f75844SAndroid Build Coastguard Worker // Remaining bitrate knowing that the low priority observer is allocated its
981*d9f75844SAndroid Build Coastguard Worker // max bitrate. We know this because it is allocated 2.0/14.0 (1/7) of the
982*d9f75844SAndroid Build Coastguard Worker // available bitrate, so 70 bps would be sufficient network bandwidth.
983*d9f75844SAndroid Build Coastguard Worker const uint32_t kRemainingBitrate = kAvailableBitrate - kLowMaxBitrate;
984*d9f75844SAndroid Build Coastguard Worker
985*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low, kMinBitrate, kLowMaxBitrate, 0, false,
986*d9f75844SAndroid Build Coastguard Worker kLowBitratePriority);
987*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_mid, kMinBitrate, kMaxBitrate, 0, false,
988*d9f75844SAndroid Build Coastguard Worker kMidBitratePriority);
989*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_high, kMinBitrate, kMaxBitrate, 0, false,
990*d9f75844SAndroid Build Coastguard Worker kHighBitratePriority);
991*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(CreateTargetRateMessage(
992*d9f75844SAndroid Build Coastguard Worker kAvailableBitrate, 0, 0, kDefaultProbingIntervalMs));
993*d9f75844SAndroid Build Coastguard Worker
994*d9f75844SAndroid Build Coastguard Worker const double kMidFractionAllocated =
995*d9f75844SAndroid Build Coastguard Worker kMidBitratePriority / (kMidBitratePriority + kHighBitratePriority);
996*d9f75844SAndroid Build Coastguard Worker const double kHighFractionAllocated =
997*d9f75844SAndroid Build Coastguard Worker kHighBitratePriority / (kMidBitratePriority + kHighBitratePriority);
998*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kLowMaxBitrate, observer_low.last_bitrate_bps_);
999*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMinBitrate + (kRemainingBitrate * kMidFractionAllocated),
1000*d9f75844SAndroid Build Coastguard Worker observer_mid.last_bitrate_bps_);
1001*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMinBitrate + (kRemainingBitrate * kHighFractionAllocated),
1002*d9f75844SAndroid Build Coastguard Worker observer_high.last_bitrate_bps_);
1003*d9f75844SAndroid Build Coastguard Worker
1004*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low);
1005*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_mid);
1006*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_high);
1007*d9f75844SAndroid Build Coastguard Worker }
1008*d9f75844SAndroid Build Coastguard Worker
1009*d9f75844SAndroid Build Coastguard Worker // Tests that after two observers are allocated bitrate to their max, the
1010*d9f75844SAndroid Build Coastguard Worker // the remaining observer is allocated what's left appropriately. This test
1011*d9f75844SAndroid Build Coastguard Worker // handles an edge case where the medium and high observer reach their
1012*d9f75844SAndroid Build Coastguard Worker // "relative" max allocation at the same time. The high has 40 to allocate
1013*d9f75844SAndroid Build Coastguard Worker // above its min, and the mid has 20 to allocate above its min, which scaled
1014*d9f75844SAndroid Build Coastguard Worker // by their bitrate priority is the same for each.
TEST_F(BitrateAllocatorTest,PriorityRateThreeObserversTwoAllocatedToMax)1015*d9f75844SAndroid Build Coastguard Worker TEST_F(BitrateAllocatorTest, PriorityRateThreeObserversTwoAllocatedToMax) {
1016*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_low;
1017*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_mid;
1018*d9f75844SAndroid Build Coastguard Worker TestBitrateObserver observer_high;
1019*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_low, 10, 40, 0, false, 2.0);
1020*d9f75844SAndroid Build Coastguard Worker // Scaled allocation above the min allocation is the same for these two,
1021*d9f75844SAndroid Build Coastguard Worker // meaning they will get allocated their max at the same time.
1022*d9f75844SAndroid Build Coastguard Worker // Scaled (target allocation) = (max - min) / bitrate priority
1023*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_mid, 10, 30, 0, false, 4.0);
1024*d9f75844SAndroid Build Coastguard Worker AddObserver(&observer_high, 10, 50, 0, false, 8.0);
1025*d9f75844SAndroid Build Coastguard Worker allocator_->OnNetworkEstimateChanged(
1026*d9f75844SAndroid Build Coastguard Worker CreateTargetRateMessage(110, 0, 0, kDefaultProbingIntervalMs));
1027*d9f75844SAndroid Build Coastguard Worker
1028*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30u, observer_low.last_bitrate_bps_);
1029*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30u, observer_mid.last_bitrate_bps_);
1030*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(50u, observer_high.last_bitrate_bps_);
1031*d9f75844SAndroid Build Coastguard Worker
1032*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_low);
1033*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_mid);
1034*d9f75844SAndroid Build Coastguard Worker allocator_->RemoveObserver(&observer_high);
1035*d9f75844SAndroid Build Coastguard Worker }
1036*d9f75844SAndroid Build Coastguard Worker
1037*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
1038