blob: 6e0cdd4d781e8b1f747f929e5a775fec3499ea13 [file] [log] [blame]
stefan@webrtc.org792f1a12015-03-04 12:24:26 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <algorithm>
kwibergb25345e2016-03-12 06:10:44 -080012#include <memory>
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000013#include <vector>
14
15#include "testing/gtest/include/gtest/gtest.h"
mflodman0e7e2592015-11-12 21:02:42 -080016#include "webrtc/call/bitrate_allocator.h"
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000017#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
18
19namespace webrtc {
20
mflodman86aabb22016-03-11 15:44:32 +010021class TestBitrateObserver : public BitrateAllocatorObserver {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000022 public:
23 TestBitrateObserver()
24 : last_bitrate_(0), last_fraction_loss_(0), last_rtt_(0) {}
25
mflodman86aabb22016-03-11 15:44:32 +010026 virtual void OnBitrateUpdated(uint32_t bitrate,
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000027 uint8_t fraction_loss,
28 int64_t rtt) {
29 last_bitrate_ = bitrate;
30 last_fraction_loss_ = fraction_loss;
31 last_rtt_ = rtt;
32 }
33 uint32_t last_bitrate_;
34 uint8_t last_fraction_loss_;
35 int64_t last_rtt_;
36};
37
38class BitrateAllocatorTest : public ::testing::Test {
39 protected:
Stefan Holmere5904162015-03-26 11:11:06 +010040 BitrateAllocatorTest() : allocator_(new BitrateAllocator()) {
41 allocator_->OnNetworkChanged(300000u, 0, 0);
42 }
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000043 ~BitrateAllocatorTest() {}
44
kwibergb25345e2016-03-12 06:10:44 -080045 std::unique_ptr<BitrateAllocator> allocator_;
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000046};
47
48TEST_F(BitrateAllocatorTest, UpdatingBitrateObserver) {
49 TestBitrateObserver bitrate_observer;
Peter Boström8e4e8b02015-09-15 15:08:03 +020050 int start_bitrate =
mflodman86aabb22016-03-11 15:44:32 +010051 allocator_->AddObserver(&bitrate_observer, 100000, 1500000);
Stefan Holmere5904162015-03-26 11:11:06 +010052 EXPECT_EQ(300000, start_bitrate);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000053 allocator_->OnNetworkChanged(200000, 0, 0);
54 EXPECT_EQ(200000u, bitrate_observer.last_bitrate_);
55
Peter Boström8e4e8b02015-09-15 15:08:03 +020056 // TODO(pbos): Expect capping to 1.5M instead of 3M when not boosting the max
mflodman0e7e2592015-11-12 21:02:42 -080057 // bitrate for FEC/retransmissions (see todo in BitrateAllocator).
Peter Boström8e4e8b02015-09-15 15:08:03 +020058 allocator_->OnNetworkChanged(4000000, 0, 0);
59 EXPECT_EQ(3000000u, bitrate_observer.last_bitrate_);
mflodman86aabb22016-03-11 15:44:32 +010060 start_bitrate = allocator_->AddObserver(&bitrate_observer, 100000, 4000000);
Peter Boström8e4e8b02015-09-15 15:08:03 +020061 EXPECT_EQ(4000000, start_bitrate);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000062
mflodman86aabb22016-03-11 15:44:32 +010063 start_bitrate = allocator_->AddObserver(&bitrate_observer, 100000, 1500000);
Peter Boström8e4e8b02015-09-15 15:08:03 +020064 EXPECT_EQ(3000000, start_bitrate);
65 EXPECT_EQ(3000000u, bitrate_observer.last_bitrate_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000066 allocator_->OnNetworkChanged(1500000, 0, 0);
67 EXPECT_EQ(1500000u, bitrate_observer.last_bitrate_);
68}
69
70TEST_F(BitrateAllocatorTest, TwoBitrateObserversOneRtcpObserver) {
71 TestBitrateObserver bitrate_observer_1;
72 TestBitrateObserver bitrate_observer_2;
Peter Boström8e4e8b02015-09-15 15:08:03 +020073 int start_bitrate =
mflodman86aabb22016-03-11 15:44:32 +010074 allocator_->AddObserver(&bitrate_observer_1, 100000, 300000);
Stefan Holmere5904162015-03-26 11:11:06 +010075 EXPECT_EQ(300000, start_bitrate);
mflodman86aabb22016-03-11 15:44:32 +010076 start_bitrate = allocator_->AddObserver(&bitrate_observer_2, 200000, 300000);
Stefan Holmere5904162015-03-26 11:11:06 +010077 EXPECT_EQ(200000, start_bitrate);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000078
79 // Test too low start bitrate, hence lower than sum of min. Min bitrates will
80 // be allocated to all observers.
81 allocator_->OnNetworkChanged(200000, 0, 50);
82 EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_);
83 EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
84 EXPECT_EQ(50, bitrate_observer_1.last_rtt_);
85 EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_);
86 EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
87 EXPECT_EQ(50, bitrate_observer_2.last_rtt_);
88
89 // Test a bitrate which should be distributed equally.
90 allocator_->OnNetworkChanged(500000, 0, 50);
91 const uint32_t kBitrateToShare = 500000 - 200000 - 100000;
92 EXPECT_EQ(100000u + kBitrateToShare / 2, bitrate_observer_1.last_bitrate_);
93 EXPECT_EQ(200000u + kBitrateToShare / 2, bitrate_observer_2.last_bitrate_);
94
Stefan Holmere5904162015-03-26 11:11:06 +010095 // Limited by 2x max bitrates since we leave room for FEC and retransmissions.
96 allocator_->OnNetworkChanged(1500000, 0, 50);
97 EXPECT_EQ(600000u, bitrate_observer_1.last_bitrate_);
98 EXPECT_EQ(600000u, bitrate_observer_2.last_bitrate_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000099}
100
101class BitrateAllocatorTestNoEnforceMin : public ::testing::Test {
102 protected:
103 BitrateAllocatorTestNoEnforceMin() : allocator_(new BitrateAllocator()) {
104 allocator_->EnforceMinBitrate(false);
Stefan Holmere5904162015-03-26 11:11:06 +0100105 allocator_->OnNetworkChanged(300000u, 0, 0);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000106 }
107 ~BitrateAllocatorTestNoEnforceMin() {}
108
kwibergb25345e2016-03-12 06:10:44 -0800109 std::unique_ptr<BitrateAllocator> allocator_;
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000110};
111
112// The following three tests verify that the EnforceMinBitrate() method works
113// as intended.
114TEST_F(BitrateAllocatorTestNoEnforceMin, OneBitrateObserver) {
115 TestBitrateObserver bitrate_observer_1;
Peter Boström8e4e8b02015-09-15 15:08:03 +0200116 int start_bitrate =
mflodman86aabb22016-03-11 15:44:32 +0100117 allocator_->AddObserver(&bitrate_observer_1, 100000, 400000);
Stefan Holmere5904162015-03-26 11:11:06 +0100118 EXPECT_EQ(300000, start_bitrate);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000119
120 // High REMB.
121 allocator_->OnNetworkChanged(150000, 0, 0);
122 EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_);
123
124 // Low REMB.
125 allocator_->OnNetworkChanged(10000, 0, 0);
126 EXPECT_EQ(10000u, bitrate_observer_1.last_bitrate_);
127
mflodman86aabb22016-03-11 15:44:32 +0100128 allocator_->RemoveObserver(&bitrate_observer_1);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000129}
130
131TEST_F(BitrateAllocatorTestNoEnforceMin, ThreeBitrateObservers) {
132 TestBitrateObserver bitrate_observer_1;
133 TestBitrateObserver bitrate_observer_2;
134 TestBitrateObserver bitrate_observer_3;
135 // Set up the observers with min bitrates at 100000, 200000, and 300000.
Peter Boström8e4e8b02015-09-15 15:08:03 +0200136 int start_bitrate =
mflodman86aabb22016-03-11 15:44:32 +0100137 allocator_->AddObserver(&bitrate_observer_1, 100000, 400000);
Stefan Holmere5904162015-03-26 11:11:06 +0100138 EXPECT_EQ(300000, start_bitrate);
139
mflodman86aabb22016-03-11 15:44:32 +0100140 start_bitrate = allocator_->AddObserver(&bitrate_observer_2, 200000, 400000);
Stefan Holmere5904162015-03-26 11:11:06 +0100141 EXPECT_EQ(200000, start_bitrate);
142 EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_);
143
mflodman86aabb22016-03-11 15:44:32 +0100144 start_bitrate = allocator_->AddObserver(&bitrate_observer_3, 300000, 400000);
Stefan Holmere5904162015-03-26 11:11:06 +0100145 EXPECT_EQ(0, start_bitrate);
146 EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_);
147 EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000148
149 // High REMB. Make sure the controllers get a fair share of the surplus
150 // (i.e., what is left after each controller gets its min rate).
151 allocator_->OnNetworkChanged(690000, 0, 0);
152 // Verify that each observer gets its min rate (sum of min rates is 600000),
153 // and that the remaining 90000 is divided equally among the three.
Stefan Holmere5904162015-03-26 11:11:06 +0100154 uint32_t bitrate_to_share = 690000u - 100000u - 200000u - 300000u;
155 EXPECT_EQ(100000u + bitrate_to_share / 3, bitrate_observer_1.last_bitrate_);
156 EXPECT_EQ(200000u + bitrate_to_share / 3, bitrate_observer_2.last_bitrate_);
157 EXPECT_EQ(300000u + bitrate_to_share / 3, bitrate_observer_3.last_bitrate_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000158
159 // High REMB, but below the sum of min bitrates.
160 allocator_->OnNetworkChanged(500000, 0, 0);
161 // Verify that the first and second observers get their min bitrates, and the
162 // third gets the remainder.
163 EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_); // Min bitrate.
164 EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_); // Min bitrate.
165 EXPECT_EQ(200000u, bitrate_observer_3.last_bitrate_); // Remainder.
166
167 // Low REMB.
168 allocator_->OnNetworkChanged(10000, 0, 0);
169 // Verify that the first observer gets all the rate, and the rest get zero.
170 EXPECT_EQ(10000u, bitrate_observer_1.last_bitrate_);
171 EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_);
172 EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_);
173
mflodman86aabb22016-03-11 15:44:32 +0100174 allocator_->RemoveObserver(&bitrate_observer_1);
175 allocator_->RemoveObserver(&bitrate_observer_2);
176 allocator_->RemoveObserver(&bitrate_observer_3);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000177}
178
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000179TEST_F(BitrateAllocatorTest, ThreeBitrateObserversLowRembEnforceMin) {
180 TestBitrateObserver bitrate_observer_1;
181 TestBitrateObserver bitrate_observer_2;
182 TestBitrateObserver bitrate_observer_3;
Peter Boström8e4e8b02015-09-15 15:08:03 +0200183 int start_bitrate =
mflodman86aabb22016-03-11 15:44:32 +0100184 allocator_->AddObserver(&bitrate_observer_1, 100000, 400000);
Stefan Holmere5904162015-03-26 11:11:06 +0100185 EXPECT_EQ(300000, start_bitrate);
186
mflodman86aabb22016-03-11 15:44:32 +0100187 start_bitrate = allocator_->AddObserver(&bitrate_observer_2, 200000, 400000);
Stefan Holmere5904162015-03-26 11:11:06 +0100188 EXPECT_EQ(200000, start_bitrate);
189 EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_);
190
mflodman86aabb22016-03-11 15:44:32 +0100191 start_bitrate = allocator_->AddObserver(&bitrate_observer_3, 300000, 400000);
Stefan Holmere5904162015-03-26 11:11:06 +0100192 EXPECT_EQ(300000, start_bitrate);
193 EXPECT_EQ(100000, static_cast<int>(bitrate_observer_1.last_bitrate_));
194 EXPECT_EQ(200000, static_cast<int>(bitrate_observer_2.last_bitrate_));
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000195
196 // Low REMB. Verify that all observers still get their respective min bitrate.
197 allocator_->OnNetworkChanged(1000, 0, 0);
198 EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_); // Min cap.
199 EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_); // Min cap.
200 EXPECT_EQ(300000u, bitrate_observer_3.last_bitrate_); // Min cap.
201
mflodman86aabb22016-03-11 15:44:32 +0100202 allocator_->RemoveObserver(&bitrate_observer_1);
203 allocator_->RemoveObserver(&bitrate_observer_2);
204 allocator_->RemoveObserver(&bitrate_observer_3);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000205}
206} // namespace webrtc