OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "webrtc/base/checks.h" | 12 #include "webrtc/base/checks.h" |
13 #include "webrtc/base/common.h" | 13 #include "webrtc/base/common.h" |
14 #include "webrtc/base/event.h" | |
15 #include "webrtc/modules/pacing/include/packet_router.h" | |
14 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_s end_time.h" | 16 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_s end_time.h" |
15 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_singl e_stream.h" | 17 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_singl e_stream.h" |
18 #include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h" | |
16 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" | 19 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" |
17 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" | 20 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" |
18 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" | 21 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" |
19 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" | 22 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" |
20 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" | 23 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
21 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" | 24 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" |
25 #include "webrtc/system_wrappers/interface/thread_wrapper.h" | |
22 #include "webrtc/test/testsupport/perf_test.h" | 26 #include "webrtc/test/testsupport/perf_test.h" |
23 #include "webrtc/video/rampup_tests.h" | 27 #include "webrtc/video/rampup_tests.h" |
24 | 28 |
25 namespace webrtc { | 29 namespace webrtc { |
26 namespace { | 30 namespace { |
27 | 31 |
28 static const int kMaxPacketSize = 1500; | 32 static const int kMaxPacketSize = 1500; |
29 const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; | 33 const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; |
30 | 34 |
31 std::vector<uint32_t> GenerateSsrcs(size_t num_streams, | 35 std::vector<uint32_t> GenerateSsrcs(size_t num_streams, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 // RtpHeaderParser and a RemoteBitrateEstimator here, but due to the current | 67 // RtpHeaderParser and a RemoteBitrateEstimator here, but due to the current |
64 // state of the RTP module we need a full module and receive statistics to | 68 // state of the RTP module we need a full module and receive statistics to |
65 // be able to produce an RTCP with REMB. | 69 // be able to produce an RTCP with REMB. |
66 RtpRtcp::Configuration config; | 70 RtpRtcp::Configuration config; |
67 config.receive_statistics = receive_stats_.get(); | 71 config.receive_statistics = receive_stats_.get(); |
68 feedback_transport_.Enable(); | 72 feedback_transport_.Enable(); |
69 config.outgoing_transport = &feedback_transport_; | 73 config.outgoing_transport = &feedback_transport_; |
70 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); | 74 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); |
71 rtp_rtcp_->SetREMBStatus(true); | 75 rtp_rtcp_->SetREMBStatus(true); |
72 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); | 76 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); |
77 packet_router_.reset(new PacketRouter()); | |
78 packet_router_->AddRtpModule(rtp_rtcp_.get()); | |
73 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, | 79 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, |
74 kAbsSendTimeExtensionId); | 80 kAbsSendTimeExtensionId); |
75 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset, | 81 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset, |
76 kTransmissionTimeOffsetExtensionId); | 82 kTransmissionTimeOffsetExtensionId); |
83 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber, | |
84 kTransportSequenceNumberExtensionId); | |
77 payload_registry_->SetRtxPayloadType(RampUpTest::kSendRtxPayloadType, | 85 payload_registry_->SetRtxPayloadType(RampUpTest::kSendRtxPayloadType, |
78 RampUpTest::kFakeSendPayloadType); | 86 RampUpTest::kFakeSendPayloadType); |
79 } | 87 } |
80 | 88 |
89 StreamObserver::~StreamObserver() { | |
90 packet_router_->RemoveRtpModule(rtp_rtcp_.get()); | |
91 } | |
92 | |
81 void StreamObserver::set_expected_bitrate_bps( | 93 void StreamObserver::set_expected_bitrate_bps( |
82 unsigned int expected_bitrate_bps) { | 94 unsigned int expected_bitrate_bps) { |
83 rtc::CritScope lock(&crit_); | 95 rtc::CritScope lock(&crit_); |
84 expected_bitrate_bps_ = expected_bitrate_bps; | 96 expected_bitrate_bps_ = expected_bitrate_bps; |
85 } | 97 } |
86 | 98 |
87 void StreamObserver::set_start_bitrate_bps(unsigned int start_bitrate_bps) { | 99 void StreamObserver::set_start_bitrate_bps(unsigned int start_bitrate_bps) { |
88 rtc::CritScope lock(&crit_); | 100 rtc::CritScope lock(&crit_); |
89 start_bitrate_bps_ = start_bitrate_bps; | 101 start_bitrate_bps_ = start_bitrate_bps; |
90 } | 102 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 } | 168 } |
157 | 169 |
158 EventTypeWrapper StreamObserver::Wait() { | 170 EventTypeWrapper StreamObserver::Wait() { |
159 return test_done_->Wait(test::CallTest::kLongTimeoutMs); | 171 return test_done_->Wait(test::CallTest::kLongTimeoutMs); |
160 } | 172 } |
161 | 173 |
162 void StreamObserver::SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe) { | 174 void StreamObserver::SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe) { |
163 remote_bitrate_estimator_.reset(rbe); | 175 remote_bitrate_estimator_.reset(rbe); |
164 } | 176 } |
165 | 177 |
178 PacketRouter* StreamObserver::GetPacketRouter() { | |
179 return packet_router_.get(); | |
180 } | |
181 | |
166 void StreamObserver::ReportResult(const std::string& measurement, | 182 void StreamObserver::ReportResult(const std::string& measurement, |
167 size_t value, | 183 size_t value, |
168 const std::string& units) { | 184 const std::string& units) { |
169 webrtc::test::PrintResult( | 185 webrtc::test::PrintResult( |
170 measurement, "", | 186 measurement, "", |
171 ::testing::UnitTest::GetInstance()->current_test_info()->name(), | 187 ::testing::UnitTest::GetInstance()->current_test_info()->name(), |
172 value, units, false); | 188 value, units, false); |
173 } | 189 } |
174 | 190 |
175 void StreamObserver::TriggerTestDone() EXCLUSIVE_LOCKS_REQUIRED(crit_) { | 191 void StreamObserver::TriggerTestDone() EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 } | 380 } |
365 break; | 381 break; |
366 } | 382 } |
367 } | 383 } |
368 } | 384 } |
369 | 385 |
370 EventTypeWrapper LowRateStreamObserver::Wait() { | 386 EventTypeWrapper LowRateStreamObserver::Wait() { |
371 return test_done_->Wait(test::CallTest::kLongTimeoutMs); | 387 return test_done_->Wait(test::CallTest::kLongTimeoutMs); |
372 } | 388 } |
373 | 389 |
390 class SendBitrateAdapter { | |
391 public: | |
392 static const int64_t kPollIntervalMs = 250; | |
393 | |
394 SendBitrateAdapter(const Call& call, | |
395 const std::vector<uint32_t>& ssrcs, | |
396 RemoteBitrateObserver* bitrate_observer) | |
397 : event_(false, false), | |
398 call_(call), | |
399 ssrcs_(ssrcs), | |
400 bitrate_observer_(bitrate_observer) { | |
401 DCHECK(bitrate_observer != nullptr); | |
402 poller_thread_ = ThreadWrapper::CreateThread(&SendBitrateAdapterThread, | |
403 this, "SendBitratePoller"); | |
404 DCHECK(poller_thread_->Start()); | |
405 } | |
406 | |
407 virtual ~SendBitrateAdapter() { | |
408 event_.Set(); | |
409 poller_thread_->Stop(); | |
410 } | |
411 | |
412 private: | |
413 static bool SendBitrateAdapterThread(void* obj) { | |
414 return static_cast<SendBitrateAdapter*>(obj)->PollStats(); | |
415 } | |
416 | |
417 bool PollStats() { | |
418 Call::Stats stats = call_.GetStats(); | |
419 | |
420 bitrate_observer_->OnReceiveBitrateChanged(ssrcs_, | |
421 stats.send_bandwidth_bps); | |
422 return !event_.Wait(kPollIntervalMs); | |
423 } | |
424 | |
425 rtc::Event event_; | |
426 rtc::scoped_ptr<ThreadWrapper> poller_thread_; | |
427 const Call& call_; | |
428 const std::vector<uint32_t> ssrcs_; | |
429 RemoteBitrateObserver* const bitrate_observer_; | |
430 }; | |
431 | |
374 void RampUpTest::RunRampUpTest(size_t num_streams, | 432 void RampUpTest::RunRampUpTest(size_t num_streams, |
375 unsigned int start_bitrate_bps, | 433 unsigned int start_bitrate_bps, |
376 const std::string& extension_type, | 434 const std::string& extension_type, |
377 bool rtx, | 435 bool rtx, |
378 bool red) { | 436 bool red) { |
379 std::vector<uint32_t> ssrcs(GenerateSsrcs(num_streams, 100)); | 437 std::vector<uint32_t> ssrcs(GenerateSsrcs(num_streams, 100)); |
380 std::vector<uint32_t> rtx_ssrcs(GenerateSsrcs(num_streams, 200)); | 438 std::vector<uint32_t> rtx_ssrcs(GenerateSsrcs(num_streams, 200)); |
381 StreamObserver::SsrcMap rtx_ssrc_map; | 439 StreamObserver::SsrcMap rtx_ssrc_map; |
382 if (rtx) { | 440 if (rtx) { |
383 for (size_t i = 0; i < ssrcs.size(); ++i) | 441 for (size_t i = 0; i < ssrcs.size(); ++i) |
384 rtx_ssrc_map[rtx_ssrcs[i]] = ssrcs[i]; | 442 rtx_ssrc_map[rtx_ssrcs[i]] = ssrcs[i]; |
385 } | 443 } |
386 | 444 |
387 test::DirectTransport receiver_transport; | 445 test::DirectTransport receiver_transport; |
388 StreamObserver stream_observer(rtx_ssrc_map, &receiver_transport, | 446 StreamObserver stream_observer(rtx_ssrc_map, &receiver_transport, |
389 Clock::GetRealTimeClock()); | 447 Clock::GetRealTimeClock()); |
390 | 448 |
391 CreateSendConfig(num_streams, &stream_observer); | 449 CreateSendConfig(num_streams, &stream_observer); |
392 send_config_.rtp.extensions.clear(); | 450 send_config_.rtp.extensions.clear(); |
393 | 451 |
452 rtc::scoped_ptr<SendBitrateAdapter> send_bitrate_adapter_; | |
453 | |
394 if (extension_type == RtpExtension::kAbsSendTime) { | 454 if (extension_type == RtpExtension::kAbsSendTime) { |
395 stream_observer.SetRemoteBitrateEstimator( | 455 stream_observer.SetRemoteBitrateEstimator( |
396 new RemoteBitrateEstimatorAbsSendTime( | 456 new RemoteBitrateEstimatorAbsSendTime( |
397 &stream_observer, Clock::GetRealTimeClock(), | 457 &stream_observer, Clock::GetRealTimeClock(), |
398 kRemoteBitrateEstimatorMinBitrateBps)); | 458 kRemoteBitrateEstimatorMinBitrateBps)); |
399 send_config_.rtp.extensions.push_back(RtpExtension( | 459 send_config_.rtp.extensions.push_back(RtpExtension( |
400 extension_type.c_str(), kAbsSendTimeExtensionId)); | 460 extension_type.c_str(), kAbsSendTimeExtensionId)); |
461 } else if (extension_type == RtpExtension::kTransportSequenceNumber) { | |
462 stream_observer.SetRemoteBitrateEstimator(new RemoteEstimatorProxy( | |
463 Clock::GetRealTimeClock(), stream_observer.GetPacketRouter())); | |
464 send_config_.rtp.extensions.push_back(RtpExtension( | |
465 extension_type.c_str(), kTransportSequenceNumberExtensionId)); | |
401 } else { | 466 } else { |
stefan-webrtc
2015/09/17 10:33:19
I'm starting to think that instead of adding a lot
sprang_webrtc
2015/09/17 15:08:28
I initially tried that but there were some obstacl
stefan-webrtc
2015/09/18 10:57:23
We can do it in a follow-up.
I don't see why we n
sprang_webrtc
2015/09/21 10:44:10
I was just under the presumption that we wanted to
stefan-webrtc
2015/09/21 11:12:07
Right, that's my thinking. I never intended to che
sprang_webrtc
2015/09/21 13:42:53
Acknowledged.
| |
402 stream_observer.SetRemoteBitrateEstimator( | 467 stream_observer.SetRemoteBitrateEstimator( |
403 new RemoteBitrateEstimatorSingleStream( | 468 new RemoteBitrateEstimatorSingleStream( |
404 &stream_observer, Clock::GetRealTimeClock(), | 469 &stream_observer, Clock::GetRealTimeClock(), |
405 kRemoteBitrateEstimatorMinBitrateBps)); | 470 kRemoteBitrateEstimatorMinBitrateBps)); |
406 send_config_.rtp.extensions.push_back(RtpExtension( | 471 send_config_.rtp.extensions.push_back(RtpExtension( |
407 extension_type.c_str(), kTransmissionTimeOffsetExtensionId)); | 472 extension_type.c_str(), kTransmissionTimeOffsetExtensionId)); |
408 } | 473 } |
409 | 474 |
410 Call::Config call_config; | 475 Call::Config call_config; |
411 if (start_bitrate_bps != 0) { | 476 if (start_bitrate_bps != 0) { |
(...skipping 30 matching lines...) Expand all Loading... | |
442 int expected_bitrate_bps = encoder_config_.streams.back().min_bitrate_bps; | 507 int expected_bitrate_bps = encoder_config_.streams.back().min_bitrate_bps; |
443 for (size_t i = 0; i < encoder_config_.streams.size() - 1; ++i) { | 508 for (size_t i = 0; i < encoder_config_.streams.size() - 1; ++i) { |
444 expected_bitrate_bps += encoder_config_.streams[i].target_bitrate_bps; | 509 expected_bitrate_bps += encoder_config_.streams[i].target_bitrate_bps; |
445 } | 510 } |
446 stream_observer.set_expected_bitrate_bps(expected_bitrate_bps); | 511 stream_observer.set_expected_bitrate_bps(expected_bitrate_bps); |
447 } | 512 } |
448 | 513 |
449 CreateStreams(); | 514 CreateStreams(); |
450 CreateFrameGeneratorCapturer(); | 515 CreateFrameGeneratorCapturer(); |
451 | 516 |
517 if (extension_type == RtpExtension::kTransportSequenceNumber) { | |
518 send_bitrate_adapter_.reset( | |
519 new SendBitrateAdapter(*sender_call_.get(), ssrcs, &stream_observer)); | |
520 } | |
452 Start(); | 521 Start(); |
453 | 522 |
454 EXPECT_EQ(kEventSignaled, stream_observer.Wait()); | 523 EXPECT_EQ(kEventSignaled, stream_observer.Wait()); |
524 send_bitrate_adapter_.reset(); | |
stefan-webrtc
2015/09/17 10:33:19
This is needed to stop the thread? Maybe comment.
sprang_webrtc
2015/09/17 15:08:28
Done.
| |
455 | 525 |
456 Stop(); | 526 Stop(); |
457 DestroyStreams(); | 527 DestroyStreams(); |
458 } | 528 } |
459 | 529 |
460 void RampUpTest::RunRampUpDownUpTest(size_t number_of_streams, | 530 void RampUpTest::RunRampUpDownUpTest(size_t number_of_streams, |
461 bool rtx, | 531 bool rtx, |
462 bool red) { | 532 bool red) { |
463 test::DirectTransport receiver_transport; | 533 test::DirectTransport receiver_transport; |
464 LowRateStreamObserver stream_observer( | 534 LowRateStreamObserver stream_observer( |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
556 } | 626 } |
557 | 627 |
558 TEST_F(RampUpTest, AbsSendTimeSimulcastByRedWithRtx) { | 628 TEST_F(RampUpTest, AbsSendTimeSimulcastByRedWithRtx) { |
559 RunRampUpTest(3, 0, RtpExtension::kAbsSendTime, true, true); | 629 RunRampUpTest(3, 0, RtpExtension::kAbsSendTime, true, true); |
560 } | 630 } |
561 | 631 |
562 TEST_F(RampUpTest, AbsSendTimeSingleStreamWithHighStartBitrate) { | 632 TEST_F(RampUpTest, AbsSendTimeSingleStreamWithHighStartBitrate) { |
563 RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kAbsSendTime, | 633 RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kAbsSendTime, |
564 false, false); | 634 false, false); |
565 } | 635 } |
636 | |
637 TEST_F(RampUpTest, TransportSequenceNumberSingleStream) { | |
638 RunRampUpTest(1, 0, RtpExtension::kTransportSequenceNumber, false, false); | |
639 } | |
640 | |
641 TEST_F(RampUpTest, TransportSequenceNumberSimulcast) { | |
642 RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, false, false); | |
643 } | |
644 | |
645 TEST_F(RampUpTest, TransportSequenceNumberSimulcastWithRtx) { | |
646 RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, true, false); | |
647 } | |
648 | |
649 TEST_F(RampUpTest, TransportSequenceNumberSimulcastByRedWithRtx) { | |
650 RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, true, true); | |
651 } | |
652 | |
653 TEST_F(RampUpTest, TransportSequenceNumberSingleStreamWithHighStartBitrate) { | |
654 RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, | |
655 RtpExtension::kTransportSequenceNumber, false, false); | |
656 } | |
566 } // namespace webrtc | 657 } // namespace webrtc |
OLD | NEW |