OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h" | 11 #include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h" |
12 | 12 |
13 #include <limits> | 13 #include <limits> |
14 #include <memory> | 14 #include <memory> |
| 15 #include <vector> |
15 | 16 |
16 #include "webrtc/test/gtest.h" | 17 #include "webrtc/test/gtest.h" |
17 | 18 |
18 namespace webrtc { | 19 namespace webrtc { |
19 namespace { | 20 namespace { |
20 constexpr uint32_t kMinBitrate = 50; | 21 constexpr uint32_t kMinBitrate = 50; |
21 constexpr uint32_t kTargetBitrate = 100; | 22 constexpr uint32_t kTargetBitrate = 100; |
22 constexpr uint32_t kMaxBitrate = 1000; | 23 constexpr uint32_t kMaxBitrate = 1000; |
23 } // namespace | 24 } // namespace |
24 | 25 |
25 class SimulcastRateAllocatorTest : public ::testing::Test { | 26 class SimulcastRateAllocatorTest : public ::testing::Test { |
26 public: | 27 public: |
27 SimulcastRateAllocatorTest() { | 28 SimulcastRateAllocatorTest() { |
28 memset(&codec_, 0, sizeof(VideoCodec)); | 29 memset(&codec_, 0, sizeof(VideoCodec)); |
29 codec_.minBitrate = kMinBitrate; | 30 codec_.minBitrate = kMinBitrate; |
30 codec_.targetBitrate = kTargetBitrate; | 31 codec_.targetBitrate = kTargetBitrate; |
31 codec_.maxBitrate = kMaxBitrate; | 32 codec_.maxBitrate = kMaxBitrate; |
32 CreateAllocator(); | 33 CreateAllocator(); |
33 } | 34 } |
34 virtual ~SimulcastRateAllocatorTest() {} | 35 virtual ~SimulcastRateAllocatorTest() {} |
35 | 36 |
36 template <size_t S> | 37 template <size_t S> |
37 void ExpectEqual(uint32_t (&expected)[S], | 38 void ExpectEqual(uint32_t (&expected)[S], |
38 const std::vector<uint32_t>& actual) { | 39 const std::vector<uint32_t>& actual) { |
39 EXPECT_EQ(S, actual.size()); | 40 EXPECT_EQ(S, actual.size()); |
40 for (size_t i = 0; i < S; ++i) | 41 for (size_t i = 0; i < S; ++i) |
41 EXPECT_EQ(expected[i], actual[i]) << "Mismatch at index " << i; | 42 EXPECT_EQ(expected[i], actual[i]) << "Mismatch at index " << i; |
42 } | 43 } |
43 | 44 |
| 45 template <size_t S> |
| 46 void ExpectEqual(uint32_t (&expected)[S], const BitrateAllocation& actual) { |
| 47 // EXPECT_EQ(S, actual.size()); |
| 48 uint32_t sum = 0; |
| 49 for (size_t i = 0; i < S; ++i) { |
| 50 uint32_t layer_bitrate = actual.GetSpatialLayerSum(i); |
| 51 EXPECT_EQ(expected[i] * 1000, layer_bitrate) << "Mismatch at index " << i; |
| 52 sum += layer_bitrate; |
| 53 } |
| 54 EXPECT_EQ(sum, actual.get_sum_bps()); |
| 55 } |
| 56 |
44 void CreateAllocator() { | 57 void CreateAllocator() { |
45 allocator_.reset(new SimulcastRateAllocator(codec_)); | 58 allocator_.reset(new SimulcastRateAllocator(codec_, nullptr)); |
| 59 } |
| 60 |
| 61 BitrateAllocation GetAllocation(uint32_t target_bitrate) { |
| 62 return allocator_->GetAllocation(target_bitrate * 1000, kDefaultFrameRate); |
46 } | 63 } |
47 | 64 |
48 protected: | 65 protected: |
| 66 static const int kDefaultFrameRate = 30; |
49 VideoCodec codec_; | 67 VideoCodec codec_; |
50 std::unique_ptr<SimulcastRateAllocator> allocator_; | 68 std::unique_ptr<SimulcastRateAllocator> allocator_; |
51 }; | 69 }; |
52 | 70 |
53 TEST_F(SimulcastRateAllocatorTest, NoSimulcastBelowMin) { | 71 TEST_F(SimulcastRateAllocatorTest, NoSimulcastBelowMin) { |
54 uint32_t expected[] = {codec_.minBitrate}; | 72 uint32_t expected[] = {codec_.minBitrate}; |
55 ExpectEqual(expected, allocator_->GetAllocation(codec_.minBitrate - 1)); | 73 ExpectEqual(expected, GetAllocation(codec_.minBitrate - 1)); |
56 ExpectEqual(expected, allocator_->GetAllocation(1)); | 74 ExpectEqual(expected, GetAllocation(1)); |
57 ExpectEqual(expected, allocator_->GetAllocation(0)); | 75 ExpectEqual(expected, GetAllocation(0)); |
58 } | 76 } |
59 | 77 |
60 TEST_F(SimulcastRateAllocatorTest, NoSimulcastAboveMax) { | 78 TEST_F(SimulcastRateAllocatorTest, NoSimulcastAboveMax) { |
61 uint32_t expected[] = {codec_.maxBitrate}; | 79 uint32_t expected[] = {codec_.maxBitrate}; |
62 ExpectEqual(expected, allocator_->GetAllocation(codec_.maxBitrate + 1)); | 80 ExpectEqual(expected, GetAllocation(codec_.maxBitrate + 1)); |
63 ExpectEqual(expected, | 81 ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max())); |
64 allocator_->GetAllocation(std::numeric_limits<uint32_t>::max())); | |
65 } | 82 } |
66 | 83 |
67 TEST_F(SimulcastRateAllocatorTest, NoSimulcastNoMax) { | 84 TEST_F(SimulcastRateAllocatorTest, NoSimulcastNoMax) { |
68 constexpr uint32_t kMax = std::numeric_limits<uint32_t>::max(); | 85 constexpr uint32_t kMax = BitrateAllocation::kMaxBitrateBps / 1000; |
69 codec_.maxBitrate = 0; | 86 codec_.maxBitrate = 0; |
70 CreateAllocator(); | 87 CreateAllocator(); |
71 | 88 |
72 uint32_t expected[] = {kMax}; | 89 uint32_t expected[] = {kMax}; |
73 ExpectEqual(expected, allocator_->GetAllocation(kMax)); | 90 ExpectEqual(expected, GetAllocation(kMax)); |
74 } | 91 } |
75 | 92 |
76 TEST_F(SimulcastRateAllocatorTest, NoSimulcastWithinLimits) { | 93 TEST_F(SimulcastRateAllocatorTest, NoSimulcastWithinLimits) { |
77 for (uint32_t bitrate = codec_.minBitrate; bitrate <= codec_.maxBitrate; | 94 for (uint32_t bitrate = codec_.minBitrate; bitrate <= codec_.maxBitrate; |
78 ++bitrate) { | 95 ++bitrate) { |
79 uint32_t expected[] = {bitrate}; | 96 uint32_t expected[] = {bitrate}; |
80 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 97 ExpectEqual(expected, GetAllocation(bitrate)); |
81 } | 98 } |
82 } | 99 } |
83 | 100 |
84 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastBelowMin) { | 101 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastBelowMin) { |
85 // With simulcast, use the min bitrate from the ss spec instead of the global. | 102 // With simulcast, use the min bitrate from the ss spec instead of the global. |
86 codec_.numberOfSimulcastStreams = 1; | 103 codec_.numberOfSimulcastStreams = 1; |
87 const uint32_t kMin = codec_.minBitrate - 10; | 104 const uint32_t kMin = codec_.minBitrate - 10; |
88 codec_.simulcastStream[0].minBitrate = kMin; | 105 codec_.simulcastStream[0].minBitrate = kMin; |
89 codec_.simulcastStream[0].targetBitrate = kTargetBitrate; | 106 codec_.simulcastStream[0].targetBitrate = kTargetBitrate; |
90 CreateAllocator(); | 107 CreateAllocator(); |
91 | 108 |
92 uint32_t expected[] = {kMin}; | 109 uint32_t expected[] = {kMin}; |
93 ExpectEqual(expected, allocator_->GetAllocation(kMin - 1)); | 110 ExpectEqual(expected, GetAllocation(kMin - 1)); |
94 ExpectEqual(expected, allocator_->GetAllocation(1)); | 111 ExpectEqual(expected, GetAllocation(1)); |
95 ExpectEqual(expected, allocator_->GetAllocation(0)); | 112 ExpectEqual(expected, GetAllocation(0)); |
96 } | 113 } |
97 | 114 |
98 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastAboveMax) { | 115 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastAboveMax) { |
99 codec_.numberOfSimulcastStreams = 1; | 116 codec_.numberOfSimulcastStreams = 1; |
100 codec_.simulcastStream[0].minBitrate = kMinBitrate; | 117 codec_.simulcastStream[0].minBitrate = kMinBitrate; |
101 const uint32_t kMax = codec_.simulcastStream[0].maxBitrate + 1000; | 118 const uint32_t kMax = codec_.simulcastStream[0].maxBitrate + 1000; |
102 codec_.simulcastStream[0].maxBitrate = kMax; | 119 codec_.simulcastStream[0].maxBitrate = kMax; |
103 CreateAllocator(); | 120 CreateAllocator(); |
104 | 121 |
105 uint32_t expected[] = {kMax}; | 122 uint32_t expected[] = {kMax}; |
106 ExpectEqual(expected, allocator_->GetAllocation(kMax + 1)); | 123 ExpectEqual(expected, GetAllocation(kMax)); |
107 ExpectEqual(expected, | 124 ExpectEqual(expected, GetAllocation(kMax + 1)); |
108 allocator_->GetAllocation(std::numeric_limits<uint32_t>::max())); | 125 ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max())); |
109 } | 126 } |
110 | 127 |
111 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) { | 128 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) { |
112 codec_.numberOfSimulcastStreams = 1; | 129 codec_.numberOfSimulcastStreams = 1; |
113 codec_.simulcastStream[0].minBitrate = kMinBitrate; | 130 codec_.simulcastStream[0].minBitrate = kMinBitrate; |
114 codec_.simulcastStream[0].targetBitrate = kTargetBitrate; | 131 codec_.simulcastStream[0].targetBitrate = kTargetBitrate; |
115 codec_.simulcastStream[0].maxBitrate = kMaxBitrate; | 132 codec_.simulcastStream[0].maxBitrate = kMaxBitrate; |
116 CreateAllocator(); | 133 CreateAllocator(); |
117 | 134 |
118 for (uint32_t bitrate = kMinBitrate; bitrate <= kMaxBitrate; ++bitrate) { | 135 for (uint32_t bitrate = kMinBitrate; bitrate <= kMaxBitrate; ++bitrate) { |
119 uint32_t expected[] = {bitrate}; | 136 uint32_t expected[] = {bitrate}; |
120 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 137 ExpectEqual(expected, GetAllocation(bitrate)); |
121 } | 138 } |
122 } | 139 } |
123 | 140 |
124 TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) { | 141 TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) { |
125 codec_.numberOfSimulcastStreams = 3; | 142 codec_.numberOfSimulcastStreams = 3; |
126 codec_.maxBitrate = 0; | 143 codec_.maxBitrate = 0; |
127 codec_.simulcastStream[0].minBitrate = 10; | 144 codec_.simulcastStream[0].minBitrate = 10; |
128 codec_.simulcastStream[0].targetBitrate = 100; | 145 codec_.simulcastStream[0].targetBitrate = 100; |
129 codec_.simulcastStream[0].maxBitrate = 500; | 146 codec_.simulcastStream[0].maxBitrate = 500; |
130 codec_.simulcastStream[1].minBitrate = 50; | 147 codec_.simulcastStream[1].minBitrate = 50; |
131 codec_.simulcastStream[1].targetBitrate = 500; | 148 codec_.simulcastStream[1].targetBitrate = 500; |
132 codec_.simulcastStream[1].maxBitrate = 1000; | 149 codec_.simulcastStream[1].maxBitrate = 1000; |
133 codec_.simulcastStream[2].minBitrate = 2000; | 150 codec_.simulcastStream[2].minBitrate = 2000; |
134 codec_.simulcastStream[2].targetBitrate = 3000; | 151 codec_.simulcastStream[2].targetBitrate = 3000; |
135 codec_.simulcastStream[2].maxBitrate = 4000; | 152 codec_.simulcastStream[2].maxBitrate = 4000; |
136 CreateAllocator(); | 153 CreateAllocator(); |
137 | 154 |
138 { | 155 { |
139 // Single stream, min bitrate. | 156 // Single stream, min bitrate. |
140 const uint32_t bitrate = codec_.simulcastStream[0].minBitrate; | 157 const uint32_t bitrate = codec_.simulcastStream[0].minBitrate; |
141 uint32_t expected[] = {bitrate, 0, 0}; | 158 uint32_t expected[] = {bitrate, 0, 0}; |
142 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 159 ExpectEqual(expected, GetAllocation(bitrate)); |
143 } | 160 } |
144 | 161 |
145 { | 162 { |
146 // Single stream at target bitrate. | 163 // Single stream at target bitrate. |
147 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate; | 164 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate; |
148 uint32_t expected[] = {bitrate, 0, 0}; | 165 uint32_t expected[] = {bitrate, 0, 0}; |
149 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 166 ExpectEqual(expected, GetAllocation(bitrate)); |
150 } | 167 } |
151 | 168 |
152 { | 169 { |
153 // Bitrate above target for first stream, but below min for the next one. | 170 // Bitrate above target for first stream, but below min for the next one. |
154 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + | 171 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
155 codec_.simulcastStream[1].minBitrate - 1; | 172 codec_.simulcastStream[1].minBitrate - 1; |
156 uint32_t expected[] = {bitrate, 0, 0}; | 173 uint32_t expected[] = {bitrate, 0, 0}; |
157 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 174 ExpectEqual(expected, GetAllocation(bitrate)); |
158 } | 175 } |
159 | 176 |
160 { | 177 { |
161 // Just enough for two streams. | 178 // Just enough for two streams. |
162 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + | 179 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
163 codec_.simulcastStream[1].minBitrate; | 180 codec_.simulcastStream[1].minBitrate; |
164 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, | 181 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
165 codec_.simulcastStream[1].minBitrate, 0}; | 182 codec_.simulcastStream[1].minBitrate, 0}; |
166 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 183 ExpectEqual(expected, GetAllocation(bitrate)); |
167 } | 184 } |
168 | 185 |
169 { | 186 { |
170 // Second stream maxed out, but not enough for third. | 187 // Second stream maxed out, but not enough for third. |
171 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + | 188 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
172 codec_.simulcastStream[1].maxBitrate; | 189 codec_.simulcastStream[1].maxBitrate; |
173 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, | 190 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
174 codec_.simulcastStream[1].maxBitrate, 0}; | 191 codec_.simulcastStream[1].maxBitrate, 0}; |
175 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 192 ExpectEqual(expected, GetAllocation(bitrate)); |
176 } | 193 } |
177 | 194 |
178 { | 195 { |
179 // First two streams maxed out, but not enough for third. Nowhere to put | 196 // First two streams maxed out, but not enough for third. Nowhere to put |
180 // remaining bits. | 197 // remaining bits. |
181 const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate + | 198 const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate + |
182 codec_.simulcastStream[1].maxBitrate + 499; | 199 codec_.simulcastStream[1].maxBitrate + 499; |
183 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, | 200 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
184 codec_.simulcastStream[1].maxBitrate, 0}; | 201 codec_.simulcastStream[1].maxBitrate, 0}; |
185 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 202 ExpectEqual(expected, GetAllocation(bitrate)); |
186 } | 203 } |
187 | 204 |
188 { | 205 { |
189 // Just enough for all three streams. | 206 // Just enough for all three streams. |
190 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + | 207 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
191 codec_.simulcastStream[1].targetBitrate + | 208 codec_.simulcastStream[1].targetBitrate + |
192 codec_.simulcastStream[2].minBitrate; | 209 codec_.simulcastStream[2].minBitrate; |
193 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, | 210 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
194 codec_.simulcastStream[1].targetBitrate, | 211 codec_.simulcastStream[1].targetBitrate, |
195 codec_.simulcastStream[2].minBitrate}; | 212 codec_.simulcastStream[2].minBitrate}; |
196 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 213 ExpectEqual(expected, GetAllocation(bitrate)); |
197 } | 214 } |
198 | 215 |
199 { | 216 { |
200 // Third maxed out. | 217 // Third maxed out. |
201 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + | 218 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
202 codec_.simulcastStream[1].targetBitrate + | 219 codec_.simulcastStream[1].targetBitrate + |
203 codec_.simulcastStream[2].maxBitrate; | 220 codec_.simulcastStream[2].maxBitrate; |
204 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, | 221 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
205 codec_.simulcastStream[1].targetBitrate, | 222 codec_.simulcastStream[1].targetBitrate, |
206 codec_.simulcastStream[2].maxBitrate}; | 223 codec_.simulcastStream[2].maxBitrate}; |
207 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); | 224 ExpectEqual(expected, GetAllocation(bitrate)); |
208 } | 225 } |
209 } | 226 } |
210 | 227 |
211 TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrate) { | 228 TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrate) { |
212 EXPECT_EQ(codec_.maxBitrate, allocator_->GetPreferedBitrate()); | 229 EXPECT_EQ(codec_.maxBitrate, |
| 230 allocator_->GetPreferedBitrate(codec_.maxFramerate)); |
213 } | 231 } |
214 | 232 |
215 TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrateSimulcast) { | 233 TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrateSimulcast) { |
216 codec_.numberOfSimulcastStreams = 3; | 234 codec_.numberOfSimulcastStreams = 3; |
217 codec_.maxBitrate = 999999; | 235 codec_.maxBitrate = 999999; |
218 codec_.simulcastStream[0].minBitrate = 10; | 236 codec_.simulcastStream[0].minBitrate = 10; |
219 codec_.simulcastStream[0].targetBitrate = 100; | 237 codec_.simulcastStream[0].targetBitrate = 100; |
220 | 238 |
221 codec_.simulcastStream[0].maxBitrate = 500; | 239 codec_.simulcastStream[0].maxBitrate = 500; |
222 codec_.simulcastStream[1].minBitrate = 50; | 240 codec_.simulcastStream[1].minBitrate = 50; |
223 codec_.simulcastStream[1].targetBitrate = 500; | 241 codec_.simulcastStream[1].targetBitrate = 500; |
224 codec_.simulcastStream[1].maxBitrate = 1000; | 242 codec_.simulcastStream[1].maxBitrate = 1000; |
225 | 243 |
226 codec_.simulcastStream[2].minBitrate = 2000; | 244 codec_.simulcastStream[2].minBitrate = 2000; |
227 codec_.simulcastStream[2].targetBitrate = 3000; | 245 codec_.simulcastStream[2].targetBitrate = 3000; |
228 codec_.simulcastStream[2].maxBitrate = 4000; | 246 codec_.simulcastStream[2].maxBitrate = 4000; |
229 CreateAllocator(); | 247 CreateAllocator(); |
230 | 248 |
231 uint32_t preferred_bitrate; | 249 uint32_t preferred_bitrate; |
232 preferred_bitrate = codec_.simulcastStream[0].targetBitrate; | 250 preferred_bitrate = codec_.simulcastStream[0].targetBitrate; |
233 preferred_bitrate += codec_.simulcastStream[1].targetBitrate; | 251 preferred_bitrate += codec_.simulcastStream[1].targetBitrate; |
234 preferred_bitrate += codec_.simulcastStream[2].maxBitrate; | 252 preferred_bitrate += codec_.simulcastStream[2].maxBitrate; |
235 | 253 |
236 EXPECT_EQ(preferred_bitrate, allocator_->GetPreferedBitrate()); | 254 EXPECT_EQ(preferred_bitrate, |
| 255 allocator_->GetPreferedBitrate(codec_.maxFramerate)); |
237 } | 256 } |
238 | 257 |
239 } // namespace webrtc | 258 } // namespace webrtc |
OLD | NEW |