OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 | 105 |
106 private: | 106 private: |
107 TestBitrateObserver observer_; | 107 TestBitrateObserver observer_; |
108 SimulatedClock simulated_clock_; | 108 SimulatedClock simulated_clock_; |
109 | 109 |
110 protected: | 110 protected: |
111 NadaBweSender nada_sender_; | 111 NadaBweSender nada_sender_; |
112 }; | 112 }; |
113 | 113 |
114 class NadaReceiverSideTest : public ::testing::Test { | 114 class NadaReceiverSideTest : public ::testing::Test { |
115 protected: | 115 public: |
116 NadaReceiverSideTest() : nada_receiver_(kFlowId) {} | 116 NadaReceiverSideTest() : nada_receiver_(kFlowId) {} |
117 ~NadaReceiverSideTest() {} | 117 ~NadaReceiverSideTest() {} |
118 | 118 |
119 const int kFlowId = 0; | 119 protected: |
120 const int kFlowId = 1; // Arbitrary. | |
120 NadaBweReceiver nada_receiver_; | 121 NadaBweReceiver nada_receiver_; |
121 }; | 122 }; |
122 | 123 |
123 class NadaFbGenerator { | 124 class NadaFbGenerator { |
124 public: | 125 public: |
125 NadaFbGenerator(); | 126 NadaFbGenerator(); |
126 | 127 |
127 static NadaFeedback NotCongestedFb(size_t receiving_rate, | 128 static NadaFeedback NotCongestedFb(size_t receiving_rate, |
128 int64_t ref_signal_ms, | 129 int64_t ref_signal_ms, |
129 int64_t send_time_ms) { | 130 int64_t send_time_ms) { |
(...skipping 28 matching lines...) Expand all Loading... | |
158 } | 159 } |
159 | 160 |
160 private: | 161 private: |
161 // Arbitrary values, won't change these test results. | 162 // Arbitrary values, won't change these test results. |
162 static const int kFlowId = 2; | 163 static const int kFlowId = 2; |
163 static const int64_t kNowMs = 1000; | 164 static const int64_t kNowMs = 1000; |
164 }; | 165 }; |
165 | 166 |
166 // Verify if AcceleratedRampUp is called and that bitrate increases. | 167 // Verify if AcceleratedRampUp is called and that bitrate increases. |
167 TEST_F(NadaSenderSideTest, AcceleratedRampUp) { | 168 TEST_F(NadaSenderSideTest, AcceleratedRampUp) { |
168 const int64_t kRefSignalMs = 3; | 169 const int64_t kRefSignalMs = 1; |
169 const int64_t kOneWayDelayMs = 50; | 170 const int64_t kOneWayDelayMs = 50; |
170 int original_bitrate = 2 * NadaBweSender::kMinRefRateKbps; | 171 int original_bitrate = 2 * kMinBitrateKbps; |
171 size_t receiving_rate = static_cast<size_t>(original_bitrate); | 172 size_t receiving_rate = static_cast<size_t>(original_bitrate); |
172 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; | 173 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; |
173 | 174 |
174 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( | 175 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( |
175 receiving_rate, kRefSignalMs, send_time_ms); | 176 receiving_rate, kRefSignalMs, send_time_ms); |
176 | 177 |
177 nada_sender_.set_original_operating_mode(true); | 178 nada_sender_.set_original_operating_mode(true); |
178 nada_sender_.set_bitrate_kbps(original_bitrate); | 179 nada_sender_.set_bitrate_kbps(original_bitrate); |
179 | 180 |
180 // Trigger AcceleratedRampUp mode. | 181 // Trigger AcceleratedRampUp mode. |
(...skipping 11 matching lines...) Expand all Loading... | |
192 nada_sender_.GiveFeedback(not_congested_fb); | 193 nada_sender_.GiveFeedback(not_congested_fb); |
193 bitrate_1_kbps = nada_sender_.bitrate_kbps(); | 194 bitrate_1_kbps = nada_sender_.bitrate_kbps(); |
194 EXPECT_GT(bitrate_1_kbps, original_bitrate); | 195 EXPECT_GT(bitrate_1_kbps, original_bitrate); |
195 nada_sender_.AcceleratedRampUp(not_congested_fb); | 196 nada_sender_.AcceleratedRampUp(not_congested_fb); |
196 EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps); | 197 EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps); |
197 } | 198 } |
198 | 199 |
199 // Verify if AcceleratedRampDown is called and if bitrate decreases. | 200 // Verify if AcceleratedRampDown is called and if bitrate decreases. |
200 TEST_F(NadaSenderSideTest, AcceleratedRampDown) { | 201 TEST_F(NadaSenderSideTest, AcceleratedRampDown) { |
201 const int64_t kOneWayDelayMs = 50; | 202 const int64_t kOneWayDelayMs = 50; |
202 int original_bitrate = 3 * NadaBweSender::kMinRefRateKbps; | 203 int original_bitrate = 3 * kMinBitrateKbps; |
203 size_t receiving_rate = static_cast<size_t>(original_bitrate); | 204 size_t receiving_rate = static_cast<size_t>(original_bitrate); |
204 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; | 205 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; |
205 | 206 |
206 NadaFeedback congested_fb = | 207 NadaFeedback congested_fb = |
207 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); | 208 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); |
208 | 209 |
209 nada_sender_.set_original_operating_mode(false); | 210 nada_sender_.set_original_operating_mode(false); |
210 nada_sender_.set_bitrate_kbps(original_bitrate); | 211 nada_sender_.set_bitrate_kbps(original_bitrate); |
211 nada_sender_.GiveFeedback(congested_fb); // Trigger AcceleratedRampDown mode. | 212 nada_sender_.GiveFeedback(congested_fb); // Trigger AcceleratedRampDown mode. |
212 int bitrate_1_kbps = nada_sender_.bitrate_kbps(); | 213 int bitrate_1_kbps = nada_sender_.bitrate_kbps(); |
213 EXPECT_LE(bitrate_1_kbps, original_bitrate * 0.9f + 0.5f); | 214 EXPECT_LE(bitrate_1_kbps, original_bitrate * 0.9f + 0.5f); |
214 EXPECT_LT(bitrate_1_kbps, original_bitrate); | 215 EXPECT_LT(bitrate_1_kbps, original_bitrate); |
215 | 216 |
216 // Updates the bitrate according to the receiving rate and other constant | 217 // Updates the bitrate according to the receiving rate and other constant |
217 // parameters. | 218 // parameters. |
218 nada_sender_.AcceleratedRampDown(congested_fb); | 219 nada_sender_.AcceleratedRampDown(congested_fb); |
219 int bitrate_2_kbps = | 220 int bitrate_2_kbps = std::max(nada_sender_.bitrate_kbps(), kMinBitrateKbps); |
220 std::max(nada_sender_.bitrate_kbps(), NadaBweSender::kMinRefRateKbps); | |
221 EXPECT_EQ(bitrate_2_kbps, bitrate_1_kbps); | 221 EXPECT_EQ(bitrate_2_kbps, bitrate_1_kbps); |
222 } | 222 } |
223 | 223 |
224 TEST_F(NadaSenderSideTest, GradualRateUpdate) { | 224 TEST_F(NadaSenderSideTest, GradualRateUpdate) { |
225 const int64_t kDeltaSMs = 20; | 225 const int64_t kDeltaSMs = 20; |
226 const int64_t kRefSignalMs = 20; | 226 const int64_t kRefSignalMs = 20; |
227 const int64_t kOneWayDelayMs = 50; | 227 const int64_t kOneWayDelayMs = 50; |
228 int original_bitrate = 2 * NadaBweSender::kMinRefRateKbps; | 228 int original_bitrate = 2 * kMinBitrateKbps; |
229 size_t receiving_rate = static_cast<size_t>(original_bitrate); | 229 size_t receiving_rate = static_cast<size_t>(original_bitrate); |
230 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; | 230 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; |
231 | 231 |
232 NadaFeedback congested_fb = | 232 NadaFeedback congested_fb = |
233 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); | 233 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); |
234 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( | 234 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( |
235 original_bitrate, kRefSignalMs, send_time_ms); | 235 original_bitrate, kRefSignalMs, send_time_ms); |
236 | 236 |
237 nada_sender_.set_bitrate_kbps(original_bitrate); | 237 nada_sender_.set_bitrate_kbps(original_bitrate); |
238 double smoothing_factor = 0.0; | 238 double smoothing_factor = 0.0; |
239 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor); | 239 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor); |
240 EXPECT_EQ(nada_sender_.bitrate_kbps(), original_bitrate); | 240 EXPECT_EQ(nada_sender_.bitrate_kbps(), original_bitrate); |
241 | 241 |
242 smoothing_factor = 1.0; | 242 smoothing_factor = 1.0; |
243 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor); | 243 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor); |
244 EXPECT_LT(nada_sender_.bitrate_kbps(), original_bitrate); | 244 EXPECT_LT(nada_sender_.bitrate_kbps(), original_bitrate); |
245 | 245 |
246 nada_sender_.set_bitrate_kbps(original_bitrate); | 246 nada_sender_.set_bitrate_kbps(original_bitrate); |
247 nada_sender_.GradualRateUpdate(not_congested_fb, kDeltaSMs, smoothing_factor); | 247 nada_sender_.GradualRateUpdate(not_congested_fb, kDeltaSMs, smoothing_factor); |
248 EXPECT_GT(nada_sender_.bitrate_kbps(), original_bitrate); | 248 EXPECT_GT(nada_sender_.bitrate_kbps(), original_bitrate); |
249 } | 249 } |
250 | 250 |
251 // Sending bitrate should decrease and reach its Min bound. | 251 // Sending bitrate should decrease and reach its Min bound. |
252 TEST_F(NadaSenderSideTest, VeryLowBandwith) { | 252 TEST_F(NadaSenderSideTest, VeryLowBandwith) { |
253 const int64_t kOneWayDelayMs = 50; | 253 const int64_t kOneWayDelayMs = 50; |
254 const int kMin = NadaBweSender::kMinRefRateKbps; | 254 |
255 size_t receiving_rate = static_cast<size_t>(kMin); | 255 size_t receiving_rate = static_cast<size_t>(kMinBitrateKbps); |
256 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; | 256 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; |
257 | 257 |
258 NadaFeedback extremely_congested_fb = | 258 NadaFeedback extremely_congested_fb = |
259 NadaFbGenerator::ExtremelyCongestedFb(receiving_rate, send_time_ms); | 259 NadaFbGenerator::ExtremelyCongestedFb(receiving_rate, send_time_ms); |
260 NadaFeedback congested_fb = | 260 NadaFeedback congested_fb = |
261 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); | 261 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); |
262 | 262 |
263 nada_sender_.set_bitrate_kbps(5 * kMin); | 263 nada_sender_.set_bitrate_kbps(5 * kMinBitrateKbps); |
264 nada_sender_.set_original_operating_mode(true); | 264 nada_sender_.set_original_operating_mode(true); |
265 for (int i = 0; i < 100; ++i) { | 265 for (int i = 0; i < 100; ++i) { |
266 // Trigger GradualRateUpdate mode. | 266 // Trigger GradualRateUpdate mode. |
267 nada_sender_.GiveFeedback(extremely_congested_fb); | 267 nada_sender_.GiveFeedback(extremely_congested_fb); |
268 } | 268 } |
269 // The original implementation doesn't allow the bitrate to stay at kMin, | 269 // The original implementation doesn't allow the bitrate to stay at kMin, |
270 // even if the congestion signal is very high. | 270 // even if the congestion signal is very high. |
271 EXPECT_GE(nada_sender_.bitrate_kbps(), kMin); | 271 EXPECT_GE(nada_sender_.bitrate_kbps(), kMinBitrateKbps); |
272 | 272 |
273 nada_sender_.set_original_operating_mode(false); | 273 nada_sender_.set_original_operating_mode(false); |
274 nada_sender_.set_bitrate_kbps(5 * kMin); | 274 nada_sender_.set_bitrate_kbps(5 * kMinBitrateKbps); |
275 | 275 |
276 for (int i = 0; i < 100; ++i) { | 276 for (int i = 0; i < 1000; ++i) { |
277 int previous_bitrate = nada_sender_.bitrate_kbps(); | 277 int previous_bitrate = nada_sender_.bitrate_kbps(); |
278 // Trigger AcceleratedRampDown mode. | 278 // Trigger AcceleratedRampDown mode. |
279 nada_sender_.GiveFeedback(congested_fb); | 279 nada_sender_.GiveFeedback(congested_fb); |
280 EXPECT_LE(nada_sender_.bitrate_kbps(), previous_bitrate); | 280 EXPECT_LE(nada_sender_.bitrate_kbps(), previous_bitrate); |
281 } | 281 } |
282 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMin); | 282 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMinBitrateKbps); |
283 } | 283 } |
284 | 284 |
285 // Sending bitrate should increase and reach its Max bound. | 285 // Sending bitrate should increase and reach its Max bound. |
286 TEST_F(NadaSenderSideTest, VeryHighBandwith) { | 286 TEST_F(NadaSenderSideTest, VeryHighBandwith) { |
287 const int64_t kOneWayDelayMs = 50; | 287 const int64_t kOneWayDelayMs = 50; |
288 const int kMax = NadaBweSender::kMaxRefRateKbps; | 288 const size_t kRecentReceivingRate = static_cast<size_t>(kMaxBitrateKbps); |
289 const size_t kRecentReceivingRate = static_cast<size_t>(kMax); | 289 const int64_t kRefSignalMs = 1; |
290 const int64_t kRefSignalMs = 5; | |
291 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; | 290 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; |
292 | 291 |
293 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( | 292 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( |
294 kRecentReceivingRate, kRefSignalMs, send_time_ms); | 293 kRecentReceivingRate, kRefSignalMs, send_time_ms); |
295 | 294 |
296 nada_sender_.set_original_operating_mode(true); | 295 nada_sender_.set_original_operating_mode(true); |
297 for (int i = 0; i < 100; ++i) { | 296 for (int i = 0; i < 100; ++i) { |
298 int previous_bitrate = nada_sender_.bitrate_kbps(); | 297 int previous_bitrate = nada_sender_.bitrate_kbps(); |
299 nada_sender_.GiveFeedback(not_congested_fb); | 298 nada_sender_.GiveFeedback(not_congested_fb); |
300 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate); | 299 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate); |
301 } | 300 } |
302 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMax); | 301 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps); |
303 | 302 |
304 nada_sender_.set_original_operating_mode(false); | 303 nada_sender_.set_original_operating_mode(false); |
305 nada_sender_.set_bitrate_kbps(NadaBweSender::kMinRefRateKbps); | 304 nada_sender_.set_bitrate_kbps(kMinBitrateKbps); |
306 | 305 |
307 for (int i = 0; i < 100; ++i) { | 306 for (int i = 0; i < 100; ++i) { |
308 int previous_bitrate = nada_sender_.bitrate_kbps(); | 307 int previous_bitrate = nada_sender_.bitrate_kbps(); |
309 nada_sender_.GiveFeedback(not_congested_fb); | 308 nada_sender_.GiveFeedback(not_congested_fb); |
310 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate); | 309 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate); |
311 } | 310 } |
312 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMax); | 311 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps); |
313 } | 312 } |
314 | 313 |
315 TEST_F(NadaReceiverSideTest, ReceivingRateNoPackets) { | 314 TEST_F(NadaReceiverSideTest, FeedbackInitialCases) { |
316 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), static_cast<size_t>(0)); | 315 // Should not send feedback until 100ms. |
316 NadaFeedback* nada_feedback = | |
stefan-webrtc
2015/07/15 12:17:50
scoped_ptr
magalhaesc
2015/07/15 12:32:35
Done.
| |
317 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(0)); | |
318 EXPECT_EQ(nada_feedback, nullptr); | |
319 | |
320 // Send feedback before receiving any packet. | |
321 nada_feedback = static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(100)); | |
322 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), -1); | |
323 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L); | |
324 EXPECT_EQ(nada_feedback->congestion_signal(), 0L); | |
325 EXPECT_EQ(nada_feedback->derivative(), 0.0f); | |
326 EXPECT_EQ(nada_feedback->receiving_rate(), 0.0f); | |
327 | |
328 delete nada_feedback; | |
317 } | 329 } |
318 | 330 |
319 TEST_F(NadaReceiverSideTest, ReceivingRateSinglePacket) { | 331 TEST_F(NadaReceiverSideTest, FeedbackEmptyQueues) { |
320 const size_t kPayloadSizeBytes = 500 * 1000; | 332 const int64_t kTimeGapMs = 50; // Between each packet. |
321 const int64_t kSendTimeUs = 300 * 1000; | 333 const int64_t kOneWayDelayMs = 50; |
322 const int64_t kArrivalTimeMs = kSendTimeUs / 1000 + 100; | |
323 const uint16_t kSequenceNumber = 1; | |
324 const int64_t kTimeWindowMs = NadaBweReceiver::kReceivingRateTimeWindowMs; | |
325 | 334 |
326 const MediaPacket media_packet(kFlowId, kSendTimeUs, kPayloadSizeBytes, | 335 // No added latency, delay = kOneWayDelayMs. |
327 kSequenceNumber); | 336 for (int i = 1; i < 10; ++i) { |
328 nada_receiver_.ReceivePacket(kArrivalTimeMs, media_packet); | |
329 | |
330 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeWindowMs; | |
331 | |
332 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps); | |
333 } | |
334 | |
335 TEST_F(NadaReceiverSideTest, ReceivingRateLargePackets) { | |
336 const size_t kPayloadSizeBytes = 3000 * 1000; | |
337 const int64_t kTimeGapMs = 3000; // Between each packet. | |
338 const int64_t kOneWayDelayMs = 1000; | |
339 | |
340 for (int i = 1; i < 5; ++i) { | |
341 int64_t send_time_us = i * kTimeGapMs * 1000; | 337 int64_t send_time_us = i * kTimeGapMs * 1000; |
342 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; | 338 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; |
343 uint16_t sequence_number = i; | 339 uint16_t sequence_number = static_cast<uint16_t>(i); |
344 const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes, | 340 // Payload sizes are not important here. |
345 sequence_number); | 341 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number); |
346 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); | 342 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); |
347 } | 343 } |
348 | 344 |
349 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeGapMs; | 345 // Baseline delay will be equal kOneWayDelayMs. |
350 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps); | 346 NadaFeedback* nada_feedback = |
347 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(100)); | |
348 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), 0L); | |
349 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L); | |
350 EXPECT_EQ(nada_feedback->congestion_signal(), 0L); | |
351 EXPECT_EQ(nada_feedback->derivative(), 0.0f); | |
352 | |
353 delete nada_feedback; | |
351 } | 354 } |
352 | 355 |
353 TEST_F(NadaReceiverSideTest, ReceivingRateSmallPackets) { | 356 TEST_F(NadaReceiverSideTest, FeedbackIncreasingDelay) { |
354 const size_t kPayloadSizeBytes = 100 * 1000; | 357 // Since packets are 100ms apart, each one corresponds to a feedback. |
355 const int64_t kTimeGapMs = 50; // Between each packet. | 358 const int64_t kTimeGapMs = 100; // Between each packet. |
356 const int64_t kOneWayDelayMs = 50; | |
357 | 359 |
358 for (int i = 1; i < 50; ++i) { | 360 // Raw delays are = [10 20 30 40 50 60 70 80] ms. |
359 int64_t send_time_us = i * kTimeGapMs * 1000; | 361 // Baseline delay will be 50 ms. |
360 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; | 362 // Delay signals should be: [0 10 20 30 40 50 60 70] ms. |
361 uint16_t sequence_number = i; | 363 const int64_t kMedianFilteredDelaysMs[] = {0, 10, 10, 20, 20, 30, 40, 50}; |
362 const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes, | 364 const int kNumPackets = ARRAY_SIZE(kMedianFilteredDelaysMs); |
363 sequence_number); | 365 const float kAlpha = 0.1f; // Used for exponential smoothing. |
364 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); | 366 |
367 int64_t exp_smoothed_delays_ms[kNumPackets]; | |
368 exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0]; | |
369 | |
370 for (int i = 1; i < kNumPackets; ++i) { | |
371 exp_smoothed_delays_ms[i] = static_cast<int64_t>( | |
372 kAlpha * kMedianFilteredDelaysMs[i] + | |
373 (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f); | |
365 } | 374 } |
366 | 375 |
367 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeGapMs; | 376 for (int i = 0; i < kNumPackets; ++i) { |
368 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps); | 377 int64_t send_time_us = (i + 1) * kTimeGapMs * 1000; |
378 int64_t arrival_time_ms = send_time_us / 1000 + 10 * (i + 1); | |
379 uint16_t sequence_number = static_cast<uint16_t>(i + 1); | |
380 // Payload sizes are not important here. | |
381 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number); | |
382 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); | |
383 | |
384 NadaFeedback* nada_feedback = | |
385 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(arrival_time_ms)); | |
386 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), | |
387 exp_smoothed_delays_ms[i]); | |
388 // Since delay signals are lower than 50ms, they will not be non-linearly | |
389 // warped. | |
390 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), | |
391 exp_smoothed_delays_ms[i]); | |
392 // Zero loss, congestion signal = queuing_delay | |
393 EXPECT_EQ(nada_feedback->congestion_signal(), exp_smoothed_delays_ms[i]); | |
394 if (i == 0) { | |
395 EXPECT_NEAR(nada_feedback->derivative(), | |
396 static_cast<float>(exp_smoothed_delays_ms[i]) / kTimeGapMs, | |
397 0.005f); | |
398 } else { | |
399 EXPECT_NEAR(nada_feedback->derivative(), | |
400 static_cast<float>(exp_smoothed_delays_ms[i] - | |
401 exp_smoothed_delays_ms[i - 1]) / | |
402 kTimeGapMs, | |
403 0.005f); | |
404 } | |
405 delete nada_feedback; | |
406 } | |
369 } | 407 } |
370 | 408 |
371 TEST_F(NadaReceiverSideTest, ReceivingRateIntermittentPackets) { | 409 int64_t Warp(int64_t input) { |
372 const size_t kPayloadSizeBytes = 100 * 1000; | 410 const int64_t kMinThreshold = 50; // Referred as d_th. |
373 const int64_t kTimeGapMs = 50; // Between each packet. | 411 const int64_t kMaxThreshold = 400; // Referred as d_max. |
374 const int64_t kFirstSendTimeMs = 0; | 412 if (input < kMinThreshold) { |
375 const int64_t kOneWayDelayMs = 50; | 413 return input; |
414 } else if (input < kMaxThreshold) { | |
415 return static_cast<int64_t>( | |
416 pow((static_cast<double>(kMaxThreshold - input)) / | |
417 (kMaxThreshold - kMinThreshold), | |
418 4.0) * | |
419 kMinThreshold); | |
420 } else { | |
421 return 0L; | |
422 } | |
423 } | |
376 | 424 |
377 // Gap between first and other packets | 425 TEST_F(NadaReceiverSideTest, FeedbackWarpedDelay) { |
378 const MediaPacket media_packet(kFlowId, kFirstSendTimeMs, kPayloadSizeBytes, | 426 // Since packets are 100ms apart, each one corresponds to a feedback. |
379 1); | 427 const int64_t kTimeGapMs = 100; // Between each packet. |
380 nada_receiver_.ReceivePacket(kFirstSendTimeMs + kOneWayDelayMs, media_packet); | |
381 | 428 |
382 const int64_t kDelayAfterFirstPacketMs = 1000; | 429 // Raw delays are = [50 250 450 650 850 1050 1250 1450] ms. |
383 const int kNumPackets = 5; // Small enough so that all packets are covered. | 430 // Baseline delay will be 50 ms. |
384 EXPECT_LT((kNumPackets - 2) * kTimeGapMs, | 431 // Delay signals should be: [0 200 400 600 800 1000 1200 1400] ms. |
385 NadaBweReceiver::kReceivingRateTimeWindowMs); | 432 const int64_t kMedianFilteredDelaysMs[] = { |
386 const int64_t kTimeWindowMs = | 433 0, 200, 200, 400, 400, 600, 800, 1000}; |
387 kDelayAfterFirstPacketMs + (kNumPackets - 2) * kTimeGapMs; | 434 const int kNumPackets = ARRAY_SIZE(kMedianFilteredDelaysMs); |
435 const float kAlpha = 0.1f; // Used for exponential smoothing. | |
388 | 436 |
389 for (int i = 2; i <= kNumPackets; ++i) { | 437 int64_t exp_smoothed_delays_ms[kNumPackets]; |
390 int64_t send_time_us = | 438 exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0]; |
391 ((i - 2) * kTimeGapMs + kFirstSendTimeMs + kDelayAfterFirstPacketMs) * | 439 |
392 1000; | 440 for (int i = 1; i < kNumPackets; ++i) { |
393 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; | 441 exp_smoothed_delays_ms[i] = static_cast<int64_t>( |
394 uint16_t sequence_number = i; | 442 kAlpha * kMedianFilteredDelaysMs[i] + |
395 const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes, | 443 (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f); |
396 sequence_number); | |
397 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); | |
398 } | 444 } |
399 | 445 |
400 const size_t kTotalReceivedKb = 8 * kNumPackets * kPayloadSizeBytes; | 446 for (int i = 0; i < kNumPackets; ++i) { |
401 const int64_t kCorrectedTimeWindowMs = | 447 int64_t send_time_us = (i + 1) * kTimeGapMs * 1000; |
402 (kTimeWindowMs * kNumPackets) / (kNumPackets - 1); | 448 int64_t arrival_time_ms = send_time_us / 1000 + 50 + 200 * i; |
403 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), | 449 uint16_t sequence_number = static_cast<uint16_t>(i + 1); |
404 kTotalReceivedKb / kCorrectedTimeWindowMs); | 450 // Payload sizes are not important here. |
405 } | 451 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number); |
452 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); | |
406 | 453 |
407 TEST_F(NadaReceiverSideTest, ReceivingRateDuplicatedPackets) { | 454 NadaFeedback* nada_feedback = |
408 const size_t kPayloadSizeBytes = 500 * 1000; | 455 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(arrival_time_ms)); |
409 const int64_t kSendTimeUs = 300 * 1000; | 456 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), |
410 const int64_t kArrivalTimeMs = kSendTimeUs / 1000 + 100; | 457 exp_smoothed_delays_ms[i]); |
411 const uint16_t kSequenceNumber = 1; | 458 // Delays can be non-linearly warped. |
412 const int64_t kTimeWindowMs = NadaBweReceiver::kReceivingRateTimeWindowMs; | 459 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), |
413 | 460 Warp(exp_smoothed_delays_ms[i])); |
414 // Insert the same packet twice. | 461 // Zero loss, congestion signal = queuing_delay |
415 for (int i = 0; i < 2; ++i) { | 462 EXPECT_EQ(nada_feedback->congestion_signal(), |
416 const MediaPacket media_packet(kFlowId, kSendTimeUs + 50 * i, | 463 Warp(exp_smoothed_delays_ms[i])); |
417 kPayloadSizeBytes, kSequenceNumber); | 464 delete nada_feedback; |
418 nada_receiver_.ReceivePacket(kArrivalTimeMs + 50 * i, media_packet); | |
419 } | 465 } |
420 // Should be counted only once. | |
421 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeWindowMs; | |
422 | |
423 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps); | |
424 } | |
425 | |
426 TEST_F(NadaReceiverSideTest, PacketLossNoPackets) { | |
427 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
428 } | |
429 | |
430 TEST_F(NadaReceiverSideTest, PacketLossSinglePacket) { | |
431 const MediaPacket media_packet(kFlowId, 0, 0, 0); | |
432 nada_receiver_.ReceivePacket(0, media_packet); | |
433 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
434 } | |
435 | |
436 TEST_F(NadaReceiverSideTest, PacketLossContiguousPackets) { | |
437 const int64_t kTimeWindowMs = NadaBweReceiver::kPacketLossTimeWindowMs; | |
438 size_t set_capacity = nada_receiver_.GetSetCapacity(); | |
439 | |
440 for (int i = 0; i < 10; ++i) { | |
441 uint16_t sequence_number = static_cast<uint16_t>(i); | |
442 // Sequence_number and flow_id are the only members that matter here. | |
443 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); | |
444 // Arrival time = 0, all packets will be considered. | |
445 nada_receiver_.ReceivePacket(0, media_packet); | |
446 } | |
447 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
448 | |
449 for (int i = 30; i > 20; i--) { | |
450 uint16_t sequence_number = static_cast<uint16_t>(i); | |
451 // Sequence_number and flow_id are the only members that matter here. | |
452 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); | |
453 // Only the packets sent in this for loop will be considered. | |
454 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet); | |
455 } | |
456 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
457 | |
458 // Should handle uint16_t overflow. | |
459 for (int i = 0xFFFF - 10; i < 0xFFFF + 10; ++i) { | |
460 uint16_t sequence_number = static_cast<uint16_t>(i); | |
461 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); | |
462 // Only the packets sent in this for loop will be considered. | |
463 nada_receiver_.ReceivePacket(4 * kTimeWindowMs, media_packet); | |
464 } | |
465 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
466 | |
467 // Should handle set overflow. | |
468 for (int i = 0; i < set_capacity * 1.5; ++i) { | |
469 uint16_t sequence_number = static_cast<uint16_t>(i); | |
470 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); | |
471 // Only the packets sent in this for loop will be considered. | |
472 nada_receiver_.ReceivePacket(6 * kTimeWindowMs, media_packet); | |
473 } | |
474 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
475 } | |
476 | |
477 // Should handle duplicates. | |
478 TEST_F(NadaReceiverSideTest, PacketLossDuplicatedPackets) { | |
479 const int64_t kTimeWindowMs = NadaBweReceiver::kPacketLossTimeWindowMs; | |
480 | |
481 for (int i = 0; i < 10; ++i) { | |
482 const MediaPacket media_packet(kFlowId, 0, 0, 0); | |
483 // Arrival time = 0, all packets will be considered. | |
484 nada_receiver_.ReceivePacket(0, media_packet); | |
485 } | |
486 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
487 | |
488 // Missing the element 5. | |
489 const uint16_t kSequenceNumbers[] = {1, 2, 3, 4, 6, 7, 8}; | |
490 const int kNumPackets = ARRAY_SIZE(kSequenceNumbers); | |
491 | |
492 // Insert each sequence number twice. | |
493 for (int i = 0; i < 2; ++i) { | |
494 for (int j = 0; j < kNumPackets; j++) { | |
495 const MediaPacket media_packet(kFlowId, 0, 0, kSequenceNumbers[j]); | |
496 // Only the packets sent in this for loop will be considered. | |
497 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet); | |
498 } | |
499 } | |
500 | |
501 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 1.0f / (kNumPackets + 1), | |
502 0.1f / (kNumPackets + 1)); | |
503 } | |
504 | |
505 TEST_F(NadaReceiverSideTest, PacketLossLakingPackets) { | |
506 size_t set_capacity = nada_receiver_.GetSetCapacity(); | |
507 EXPECT_LT(set_capacity, static_cast<size_t>(0xFFFF)); | |
508 | |
509 // Missing every other packet. | |
510 for (size_t i = 0; i < set_capacity; ++i) { | |
511 if ((i & 1) == 0) { // Only even sequence numbers. | |
512 uint16_t sequence_number = static_cast<uint16_t>(i); | |
513 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); | |
514 // Arrival time = 0, all packets will be considered. | |
515 nada_receiver_.ReceivePacket(0, media_packet); | |
516 } | |
517 } | |
518 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 0.5f, 0.01f); | |
519 } | |
520 | |
521 TEST_F(NadaReceiverSideTest, PacketLossLakingFewPackets) { | |
522 size_t set_capacity = nada_receiver_.GetSetCapacity(); | |
523 EXPECT_LT(set_capacity, static_cast<size_t>(0xFFFF)); | |
524 | |
525 const int kPeriod = 100; | |
526 // Missing one for each kPeriod packets. | |
527 for (size_t i = 0; i < set_capacity; ++i) { | |
528 if ((i % kPeriod) != 0) { | |
529 uint16_t sequence_number = static_cast<uint16_t>(i); | |
530 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); | |
531 // Arrival time = 0, all packets will be considered. | |
532 nada_receiver_.ReceivePacket(0, media_packet); | |
533 } | |
534 } | |
535 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 1.0f / kPeriod, | |
536 0.1f / kPeriod); | |
537 } | |
538 | |
539 // Packet's sequence numbers greatly apart, expect high loss. | |
540 TEST_F(NadaReceiverSideTest, PacketLossWideGap) { | |
541 const int64_t kTimeWindowMs = NadaBweReceiver::kPacketLossTimeWindowMs; | |
542 | |
543 const MediaPacket media_packet1(0, 0, 0, 1); | |
544 const MediaPacket media_packet2(0, 0, 0, 1000); | |
545 // Only these two packets will be considered. | |
546 nada_receiver_.ReceivePacket(0, media_packet1); | |
547 nada_receiver_.ReceivePacket(0, media_packet2); | |
548 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 0.998f, 0.0001f); | |
549 | |
550 const MediaPacket media_packet3(0, 0, 0, 0); | |
551 const MediaPacket media_packet4(0, 0, 0, 0x8000); | |
552 // Only these two packets will be considered. | |
553 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet3); | |
554 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet4); | |
555 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 0.99994f, 0.00001f); | |
556 } | |
557 | |
558 // Packets arriving unordered should not be counted as losted. | |
559 TEST_F(NadaReceiverSideTest, PacketLossUnorderedPackets) { | |
560 size_t num_packets = nada_receiver_.GetSetCapacity() / 2; | |
561 std::vector<uint16_t> sequence_numbers; | |
562 | |
563 for (size_t i = 0; i < num_packets; ++i) { | |
564 sequence_numbers.push_back(static_cast<uint16_t>(i + 1)); | |
565 } | |
566 | |
567 random_shuffle(sequence_numbers.begin(), sequence_numbers.end()); | |
568 | |
569 for (size_t i = 0; i < num_packets; ++i) { | |
570 const MediaPacket media_packet(kFlowId, 0, 0, sequence_numbers[i]); | |
571 // Arrival time = 0, all packets will be considered. | |
572 nada_receiver_.ReceivePacket(0, media_packet); | |
573 } | |
574 | |
575 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f); | |
576 } | 466 } |
577 | 467 |
578 TEST_F(FilterTest, MedianConstantArray) { | 468 TEST_F(FilterTest, MedianConstantArray) { |
579 MedianFilterConstantArray(); | 469 MedianFilterConstantArray(); |
580 for (int i = 0; i < kNumElements; ++i) { | 470 for (int i = 0; i < kNumElements; ++i) { |
581 EXPECT_EQ(median_filtered_[i], raw_signal_[i]); | 471 EXPECT_EQ(median_filtered_[i], raw_signal_[i]); |
582 } | 472 } |
583 } | 473 } |
584 | 474 |
585 TEST_F(FilterTest, MedianIntermittentNoise) { | 475 TEST_F(FilterTest, MedianIntermittentNoise) { |
(...skipping 16 matching lines...) Expand all Loading... | |
602 for (int i = 1; i < kNumElements; ++i) { | 492 for (int i = 1; i < kNumElements; ++i) { |
603 EXPECT_EQ( | 493 EXPECT_EQ( |
604 exp_smoothed[i], | 494 exp_smoothed[i], |
605 static_cast<int64_t>(exp_smoothed[i - 1] * (1.0f - kAlpha) + 0.5f)); | 495 static_cast<int64_t>(exp_smoothed[i - 1] * (1.0f - kAlpha) + 0.5f)); |
606 } | 496 } |
607 } | 497 } |
608 | 498 |
609 } // namespace bwe | 499 } // namespace bwe |
610 } // namespace testing | 500 } // namespace testing |
611 } // namespace webrtc | 501 } // namespace webrtc |
OLD | NEW |