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/logging/rtc_event_log/mock/mock_rtc_event_log.h" | 11 #include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h" |
12 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | 12 #include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller .h" |
13 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" | 13 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" |
14 #include "webrtc/modules/congestion_controller/include/mock/mock_congestion_cont roller.h" | 14 #include "webrtc/modules/congestion_controller/include/mock/mock_congestion_cont roller.h" |
15 #include "webrtc/modules/pacing/mock/mock_paced_sender.h" | 15 #include "webrtc/modules/pacing/mock/mock_paced_sender.h" |
16 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" | 16 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" |
17 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitra te_observer.h" | 17 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitra te_observer.h" |
18 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | |
18 #include "webrtc/system_wrappers/include/clock.h" | 19 #include "webrtc/system_wrappers/include/clock.h" |
19 #include "webrtc/test/gmock.h" | 20 #include "webrtc/test/gmock.h" |
20 #include "webrtc/test/gtest.h" | 21 #include "webrtc/test/gtest.h" |
21 | 22 |
22 using testing::_; | 23 using testing::_; |
23 using testing::AtLeast; | 24 using testing::AtLeast; |
24 using testing::NiceMock; | 25 using testing::NiceMock; |
25 using testing::Return; | 26 using testing::Return; |
26 using testing::SaveArg; | 27 using testing::SaveArg; |
27 using testing::StrictMock; | 28 using testing::StrictMock; |
28 | 29 |
29 namespace { | 30 namespace { |
31 const webrtc::PacedPacketInfo kPacingInfo0(0, 5, 2000); | |
32 const webrtc::PacedPacketInfo kPacingInfo1(1, 8, 4000); | |
30 | 33 |
31 // Helper to convert some time format to resolution used in absolute send time | 34 // Helper to convert some time format to resolution used in absolute send time |
32 // header extension, rounded upwards. |t| is the time to convert, in some | 35 // header extension, rounded upwards. |t| is the time to convert, in some |
33 // resolution. |denom| is the value to divide |t| by to get whole seconds, | 36 // resolution. |denom| is the value to divide |t| by to get whole seconds, |
34 // e.g. |denom| = 1000 if |t| is in milliseconds. | 37 // e.g. |denom| = 1000 if |t| is in milliseconds. |
35 uint32_t AbsSendTime(int64_t t, int64_t denom) { | 38 uint32_t AbsSendTime(int64_t t, int64_t denom) { |
36 return (((t << 18) + (denom >> 1)) / denom) & 0x00fffffful; | 39 return (((t << 18) + (denom >> 1)) / denom) & 0x00fffffful; |
37 } | 40 } |
38 | 41 |
42 // TODO(elad.alon): This is not meant to be landed like this. Ask reviewers | |
elad.alon_webrtc.org
2017/03/02 11:51:47
Soliciting feedback. :-)
| |
43 // where would be a good place to put ComparePacketVectors(), so that it would | |
44 // be visible to both unit-test suites. | |
45 void ComparePacketVectors(const std::vector<webrtc::PacketFeedback>& truth, | |
46 const std::vector<webrtc::PacketFeedback>& input) { | |
47 ASSERT_EQ(truth.size(), input.size()); | |
48 size_t len = truth.size(); | |
49 // truth contains the input data for the test, and input is what will be | |
50 // sent to the bandwidth estimator. truth.arrival_tims_ms is used to | |
51 // populate the transport feedback messages. As these times may be changed | |
52 // (because of resolution limits in the packets, and because of the time | |
53 // base adjustment performed by the TransportFeedbackAdapter at the first | |
54 // packet, the truth[x].arrival_time and input[x].arrival_time may not be | |
55 // equal. However, the difference must be the same for all x. | |
56 int64_t arrival_time_delta = | |
57 truth[0].arrival_time_ms - input[0].arrival_time_ms; | |
58 for (size_t i = 0; i < len; ++i) { | |
59 RTC_CHECK(truth[i].arrival_time_ms != webrtc::PacketFeedback::kNotReceived); | |
60 if (input[i].arrival_time_ms != webrtc::PacketFeedback::kNotReceived) { | |
61 EXPECT_EQ(truth[i].arrival_time_ms, | |
62 input[i].arrival_time_ms + arrival_time_delta); | |
63 } | |
64 EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms); | |
65 EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number); | |
66 EXPECT_EQ(truth[i].payload_size, input[i].payload_size); | |
67 EXPECT_EQ(truth[i].pacing_info, input[i].pacing_info); | |
68 } | |
69 } | |
39 } // namespace | 70 } // namespace |
40 | 71 |
41 namespace webrtc { | 72 namespace webrtc { |
42 namespace test { | 73 namespace test { |
43 | 74 |
44 class CongestionControllerTest : public ::testing::Test { | 75 class CongestionControllerTest : public ::testing::Test { |
45 protected: | 76 protected: |
46 CongestionControllerTest() : clock_(123456) {} | 77 CongestionControllerTest() : clock_(123456) {} |
47 ~CongestionControllerTest() override {} | 78 ~CongestionControllerTest() override {} |
48 | 79 |
49 void SetUp() override { | 80 void SetUp() override { |
50 pacer_ = new NiceMock<MockPacedSender>(); | 81 pacer_ = new NiceMock<MockPacedSender>(); |
51 std::unique_ptr<PacedSender> pacer(pacer_); // Passes ownership. | 82 std::unique_ptr<PacedSender> pacer(pacer_); // Passes ownership. |
52 controller_.reset(new CongestionController( | 83 controller_.reset(new CongestionController( |
53 &clock_, &observer_, &remote_bitrate_observer_, &event_log_, | 84 &clock_, &observer_, &remote_bitrate_observer_, &event_log_, |
54 &packet_router_, std::move(pacer))); | 85 &packet_router_, std::move(pacer), |
86 std::unique_ptr<BitrateController>( | |
87 BitrateController::CreateBitrateController(&clock_, &event_log_)))); | |
55 bandwidth_observer_.reset( | 88 bandwidth_observer_.reset( |
56 controller_->GetBitrateController()->CreateRtcpBandwidthObserver()); | 89 controller_->GetBitrateController()->CreateRtcpBandwidthObserver()); |
57 | 90 |
58 // Set the initial bitrate estimate and expect the |observer| and |pacer_| | 91 // Set the initial bitrate estimate and expect the |observer| and |pacer_| |
59 // to be updated. | 92 // to be updated. |
60 EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _)); | 93 EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _)); |
61 EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps)); | 94 EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps)); |
62 controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps); | 95 controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps); |
63 } | 96 } |
64 | 97 |
98 void OnSentPacket(const PacketFeedback& packet_feedback) { | |
99 controller_->AddPacket(packet_feedback.sequence_number, | |
100 packet_feedback.payload_size, | |
101 packet_feedback.pacing_info); | |
102 controller_->OnSentPacket(rtc::SentPacket(packet_feedback.sequence_number, | |
103 packet_feedback.send_time_ms)); | |
104 } | |
105 | |
106 class MockBitrateControllerAdapter : public MockBitrateController { | |
stefan-webrtc
2017/03/02 15:58:07
I would prefer not to have this mock, and to not e
| |
107 public: | |
108 explicit MockBitrateControllerAdapter(CongestionControllerTest* owner) | |
109 : MockBitrateController(), owner_(owner) {} | |
110 | |
111 ~MockBitrateControllerAdapter() override {} | |
112 | |
113 void OnDelayBasedBweResult(const DelayBasedBwe::Result& result) override { | |
114 owner_->target_bitrate_bps_ = | |
115 rtc::Optional<uint32_t>(result.target_bitrate_bps); | |
116 } | |
117 | |
118 CongestionControllerTest* const owner_; | |
119 }; | |
120 | |
65 SimulatedClock clock_; | 121 SimulatedClock clock_; |
66 StrictMock<MockCongestionObserver> observer_; | 122 StrictMock<MockCongestionObserver> observer_; |
67 NiceMock<MockPacedSender>* pacer_; | 123 NiceMock<MockPacedSender>* pacer_; |
68 NiceMock<MockRemoteBitrateObserver> remote_bitrate_observer_; | 124 NiceMock<MockRemoteBitrateObserver> remote_bitrate_observer_; |
69 NiceMock<MockRtcEventLog> event_log_; | 125 NiceMock<MockRtcEventLog> event_log_; |
70 std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_; | 126 std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_; |
71 PacketRouter packet_router_; | 127 PacketRouter packet_router_; |
72 std::unique_ptr<CongestionController> controller_; | 128 std::unique_ptr<CongestionController> controller_; |
73 const uint32_t kInitialBitrateBps = 60000; | 129 const uint32_t kInitialBitrateBps = 60000; |
130 rtc::Optional<uint32_t> target_bitrate_bps_; | |
74 }; | 131 }; |
75 | 132 |
76 TEST_F(CongestionControllerTest, OnNetworkChanged) { | 133 TEST_F(CongestionControllerTest, OnNetworkChanged) { |
77 // Test no change. | 134 // Test no change. |
78 clock_.AdvanceTimeMilliseconds(25); | 135 clock_.AdvanceTimeMilliseconds(25); |
79 controller_->Process(); | 136 controller_->Process(); |
80 | 137 |
81 EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 2, _, _, _)); | 138 EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 2, _, _, _)); |
82 EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps * 2)); | 139 EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps * 2)); |
83 bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2); | 140 bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 EXPECT_CALL(*pacer_, SetEstimatedBitrate(_)); | 267 EXPECT_CALL(*pacer_, SetEstimatedBitrate(_)); |
211 bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2); | 268 bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2); |
212 clock_.AdvanceTimeMilliseconds(25); | 269 clock_.AdvanceTimeMilliseconds(25); |
213 controller_->Process(); | 270 controller_->Process(); |
214 } | 271 } |
215 | 272 |
216 TEST_F(CongestionControllerTest, OnReceivedPacketWithAbsSendTime) { | 273 TEST_F(CongestionControllerTest, OnReceivedPacketWithAbsSendTime) { |
217 NiceMock<MockCongestionObserver> observer; | 274 NiceMock<MockCongestionObserver> observer; |
218 StrictMock<MockRemoteBitrateObserver> remote_bitrate_observer; | 275 StrictMock<MockRemoteBitrateObserver> remote_bitrate_observer; |
219 std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>()); | 276 std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>()); |
220 controller_.reset( | 277 controller_.reset(new CongestionController( |
221 new CongestionController(&clock_, &observer, &remote_bitrate_observer, | 278 &clock_, &observer, &remote_bitrate_observer, &event_log_, |
222 &event_log_, &packet_router_, std::move(pacer))); | 279 &packet_router_, std::move(pacer), |
280 std::unique_ptr<BitrateController>( | |
281 BitrateController::CreateBitrateController(&clock_, &event_log_)))); | |
223 | 282 |
224 size_t payload_size = 1000; | 283 size_t payload_size = 1000; |
225 RTPHeader header; | 284 RTPHeader header; |
226 header.ssrc = 0x11eb21c; | 285 header.ssrc = 0x11eb21c; |
227 header.extension.hasAbsoluteSendTime = true; | 286 header.extension.hasAbsoluteSendTime = true; |
228 | 287 |
229 std::vector<unsigned int> ssrcs; | 288 std::vector<unsigned int> ssrcs; |
230 EXPECT_CALL(remote_bitrate_observer, OnReceiveBitrateChanged(_, _)) | 289 EXPECT_CALL(remote_bitrate_observer, OnReceiveBitrateChanged(_, _)) |
231 .WillRepeatedly(SaveArg<0>(&ssrcs)); | 290 .WillRepeatedly(SaveArg<0>(&ssrcs)); |
232 | 291 |
233 for (int i = 0; i < 10; ++i) { | 292 for (int i = 0; i < 10; ++i) { |
234 clock_.AdvanceTimeMilliseconds((1000 * payload_size) / kInitialBitrateBps); | 293 clock_.AdvanceTimeMilliseconds((1000 * payload_size) / kInitialBitrateBps); |
235 int64_t now_ms = clock_.TimeInMilliseconds(); | 294 int64_t now_ms = clock_.TimeInMilliseconds(); |
236 header.extension.absoluteSendTime = AbsSendTime(now_ms, 1000); | 295 header.extension.absoluteSendTime = AbsSendTime(now_ms, 1000); |
237 controller_->OnReceivedPacket(now_ms, payload_size, header); | 296 controller_->OnReceivedPacket(now_ms, payload_size, header); |
238 } | 297 } |
239 | 298 |
240 ASSERT_EQ(1u, ssrcs.size()); | 299 ASSERT_EQ(1u, ssrcs.size()); |
241 EXPECT_EQ(header.ssrc, ssrcs[0]); | 300 EXPECT_EQ(header.ssrc, ssrcs[0]); |
242 } | 301 } |
302 | |
303 TEST_F(CongestionControllerTest, UpdatesDelayBasedEstimate) { | |
304 NiceMock<MockCongestionObserver> observer; | |
305 StrictMock<MockRemoteBitrateObserver> remote_bitrate_observer; | |
306 std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>()); | |
307 controller_.reset( | |
308 new CongestionController(&clock_, &observer, &remote_bitrate_observer, | |
309 &event_log_, &packet_router_, std::move(pacer), | |
310 std::unique_ptr<BitrateController>( | |
311 new MockBitrateControllerAdapter(this)))); | |
312 | |
313 uint16_t seq_num = 0; | |
314 size_t kPayloadSize = 1000; | |
315 // The test must run and insert packets/feedback long enough that the | |
316 // BWE computes a valid estimate. | |
317 const int64_t kRunTimeMs = 6000; | |
318 int64_t start_time_ms = clock_.TimeInMilliseconds(); | |
319 while (clock_.TimeInMilliseconds() - start_time_ms < kRunTimeMs) { | |
320 PacketFeedback packet(clock_.TimeInMilliseconds(), | |
321 clock_.TimeInMilliseconds(), seq_num, kPayloadSize, | |
322 PacedPacketInfo()); | |
323 OnSentPacket(packet); | |
324 // Create expected feedback and send into adapter. | |
325 std::unique_ptr<rtcp::TransportFeedback> feedback( | |
326 new rtcp::TransportFeedback()); | |
327 feedback->SetBase(packet.sequence_number, packet.arrival_time_ms * 1000); | |
328 EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number, | |
329 packet.arrival_time_ms * 1000)); | |
330 rtc::Buffer raw_packet = feedback->Build(); | |
331 feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(), | |
332 raw_packet.size()); | |
333 EXPECT_TRUE(feedback.get() != nullptr); | |
334 controller_->OnTransportFeedback(*feedback.get()); | |
335 clock_.AdvanceTimeMilliseconds(50); | |
336 ++seq_num; | |
337 } | |
stefan-webrtc
2017/03/02 15:58:07
Keep this loop, and also add a similar after:
whi
| |
338 | |
339 EXPECT_TRUE(target_bitrate_bps_); | |
340 } | |
341 | |
342 TEST_F(CongestionControllerTest, LongFeedbackDelays) { | |
343 // Custom setup | |
344 std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>()); | |
345 auto mock_bitrate_controller = std::unique_ptr<MockBitrateControllerAdapter>( | |
346 new MockBitrateControllerAdapter(this)); | |
347 EXPECT_CALL(*mock_bitrate_controller, SetBitrates(_, _, _)); | |
348 EXPECT_CALL(*mock_bitrate_controller, GetNetworkParameters(_, _, _)); | |
349 EXPECT_CALL(observer_, OnNetworkChanged(_, _, _, _)); | |
350 controller_.reset(new CongestionController( | |
351 &clock_, &observer_, &remote_bitrate_observer_, &event_log_, | |
352 &packet_router_, std::move(pacer), | |
353 std::unique_ptr<BitrateController>(std::move(mock_bitrate_controller)))); | |
354 controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps); | |
355 | |
356 const int64_t kFeedbackTimeoutMs = 60001; | |
357 const int kMaxConsecutiveFailedLookups = 5; | |
358 for (int i = 0; i < kMaxConsecutiveFailedLookups; ++i) { | |
359 std::vector<PacketFeedback> packets; | |
360 packets.push_back( | |
361 PacketFeedback(i * 100, 2 * i * 100, 0, 1500, kPacingInfo0)); | |
362 packets.push_back( | |
363 PacketFeedback(i * 100 + 10, 2 * i * 100 + 10, 1, 1500, kPacingInfo0)); | |
364 packets.push_back( | |
365 PacketFeedback(i * 100 + 20, 2 * i * 100 + 20, 2, 1500, kPacingInfo0)); | |
366 packets.push_back( | |
367 PacketFeedback(i * 100 + 30, 2 * i * 100 + 30, 3, 1500, kPacingInfo1)); | |
368 packets.push_back( | |
369 PacketFeedback(i * 100 + 40, 2 * i * 100 + 40, 4, 1500, kPacingInfo1)); | |
370 | |
371 for (const PacketFeedback& packet : packets) | |
372 OnSentPacket(packet); | |
373 | |
374 rtcp::TransportFeedback feedback; | |
375 feedback.SetBase(packets[0].sequence_number, | |
376 packets[0].arrival_time_ms * 1000); | |
377 | |
378 for (const PacketFeedback& packet : packets) { | |
379 EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, | |
380 packet.arrival_time_ms * 1000)); | |
381 } | |
382 | |
383 feedback.Build(); | |
384 | |
385 clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs); | |
386 PacketFeedback later_packet(kFeedbackTimeoutMs + i * 100 + 40, | |
387 kFeedbackTimeoutMs + i * 200 + 40, 5, 1500, | |
388 kPacingInfo1); | |
389 OnSentPacket(later_packet); | |
390 | |
391 controller_->OnTransportFeedback(feedback); | |
392 | |
393 // Check that packets have timed out. | |
394 for (PacketFeedback& packet : packets) { | |
395 packet.send_time_ms = -1; | |
396 packet.payload_size = 0; | |
397 packet.pacing_info = PacedPacketInfo(); | |
398 } | |
399 ComparePacketVectors(packets, controller_->GetTransportFeedbackVector()); | |
400 } | |
401 | |
402 // Target bitrate should have halved due to feedback delays. | |
403 EXPECT_EQ(kInitialBitrateBps / 2, target_bitrate_bps_); | |
404 | |
405 // Test with feedback that isn't late enough to time out. | |
406 { | |
407 std::vector<PacketFeedback> packets; | |
408 packets.push_back(PacketFeedback(100, 200, 0, 1500, kPacingInfo0)); | |
409 packets.push_back(PacketFeedback(110, 210, 1, 1500, kPacingInfo0)); | |
410 packets.push_back(PacketFeedback(120, 220, 2, 1500, kPacingInfo0)); | |
411 packets.push_back(PacketFeedback(130, 230, 3, 1500, kPacingInfo1)); | |
412 packets.push_back(PacketFeedback(140, 240, 4, 1500, kPacingInfo1)); | |
413 | |
414 for (const PacketFeedback& packet : packets) | |
415 OnSentPacket(packet); | |
416 | |
417 rtcp::TransportFeedback feedback; | |
418 feedback.SetBase(packets[0].sequence_number, | |
419 packets[0].arrival_time_ms * 1000); | |
420 | |
421 for (const PacketFeedback& packet : packets) { | |
422 EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, | |
423 packet.arrival_time_ms * 1000)); | |
424 } | |
425 | |
426 feedback.Build(); | |
427 | |
428 clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs - 1); | |
429 PacketFeedback later_packet(kFeedbackTimeoutMs + 140, | |
430 kFeedbackTimeoutMs + 240, 5, 1500, | |
431 kPacingInfo1); | |
432 OnSentPacket(later_packet); | |
433 | |
434 controller_->OnTransportFeedback(feedback); | |
435 ComparePacketVectors(packets, controller_->GetTransportFeedbackVector()); | |
436 } | |
437 } | |
243 } // namespace test | 438 } // namespace test |
244 } // namespace webrtc | 439 } // namespace webrtc |
OLD | NEW |