 Chromium Code Reviews
 Chromium Code Reviews Issue 1338203003:
  Wire up send-side bandwidth estimation.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1338203003:
  Wire up send-side bandwidth estimation.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| 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 10 matching lines...) Expand all Loading... | |
| 101 // first estimate really is as high as the start bitrate. | 113 // first estimate really is as high as the start bitrate. | 
| 102 EXPECT_GT(bitrate, 0.9 * start_bitrate_bps_); | 114 EXPECT_GT(bitrate, 0.9 * start_bitrate_bps_); | 
| 103 start_bitrate_bps_ = 0; | 115 start_bitrate_bps_ = 0; | 
| 104 } | 116 } | 
| 105 if (bitrate >= expected_bitrate_bps_) { | 117 if (bitrate >= expected_bitrate_bps_) { | 
| 106 ramp_up_finished_ms_ = clock_->TimeInMilliseconds(); | 118 ramp_up_finished_ms_ = clock_->TimeInMilliseconds(); | 
| 107 // Just trigger if there was any rtx padding packet. | 119 // Just trigger if there was any rtx padding packet. | 
| 108 if (rtx_media_ssrcs_.empty() || rtx_media_sent_ > 0) { | 120 if (rtx_media_ssrcs_.empty() || rtx_media_sent_ > 0) { | 
| 109 TriggerTestDone(); | 121 TriggerTestDone(); | 
| 110 } | 122 } | 
| 111 } | 123 } | 
| 
stefan-webrtc
2015/09/18 10:57:23
Basically we can move all of this into a thread wh
 | |
| 112 rtp_rtcp_->SetREMBData(bitrate, ssrcs); | 124 rtp_rtcp_->SetREMBData(bitrate, ssrcs); | 
| 113 rtp_rtcp_->Process(); | 125 rtp_rtcp_->Process(); | 
| 114 } | 126 } | 
| 115 | 127 | 
| 116 bool StreamObserver::SendRtp(const uint8_t* packet, size_t length) { | 128 bool StreamObserver::SendRtp(const uint8_t* packet, size_t length) { | 
| 117 rtc::CritScope lock(&crit_); | 129 rtc::CritScope lock(&crit_); | 
| 118 RTPHeader header; | 130 RTPHeader header; | 
| 119 EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header)); | 131 EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header)); | 
| 120 receive_stats_->IncomingPacket(header, length, false); | 132 receive_stats_->IncomingPacket(header, length, false); | 
| 121 payload_registry_->SetIncomingPayloadType(header); | 133 payload_registry_->SetIncomingPayloadType(header); | 
| (...skipping 34 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 RTC_DCHECK(bitrate_observer != nullptr); | |
| 402 poller_thread_ = ThreadWrapper::CreateThread(&SendBitrateAdapterThread, | |
| 403 this, "SendBitratePoller"); | |
| 404 RTC_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 { | 
| 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; | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after 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()); | 
| 455 | 524 | 
| 525 // Destroy the SendBitrateAdapter (if any) to stop the poller thread in it, | |
| 526 // otherwise we might get a data race with the destruction of the call. | |
| 527 send_bitrate_adapter_.reset(); | |
| 528 | |
| 456 Stop(); | 529 Stop(); | 
| 457 DestroyStreams(); | 530 DestroyStreams(); | 
| 458 } | 531 } | 
| 459 | 532 | 
| 460 void RampUpTest::RunRampUpDownUpTest(size_t number_of_streams, | 533 void RampUpTest::RunRampUpDownUpTest(size_t number_of_streams, | 
| 461 bool rtx, | 534 bool rtx, | 
| 462 bool red) { | 535 bool red) { | 
| 463 test::DirectTransport receiver_transport; | 536 test::DirectTransport receiver_transport; | 
| 464 LowRateStreamObserver stream_observer( | 537 LowRateStreamObserver stream_observer( | 
| 465 &receiver_transport, Clock::GetRealTimeClock(), number_of_streams, rtx); | 538 &receiver_transport, Clock::GetRealTimeClock(), number_of_streams, rtx); | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 } | 629 } | 
| 557 | 630 | 
| 558 TEST_F(RampUpTest, AbsSendTimeSimulcastByRedWithRtx) { | 631 TEST_F(RampUpTest, AbsSendTimeSimulcastByRedWithRtx) { | 
| 559 RunRampUpTest(3, 0, RtpExtension::kAbsSendTime, true, true); | 632 RunRampUpTest(3, 0, RtpExtension::kAbsSendTime, true, true); | 
| 560 } | 633 } | 
| 561 | 634 | 
| 562 TEST_F(RampUpTest, AbsSendTimeSingleStreamWithHighStartBitrate) { | 635 TEST_F(RampUpTest, AbsSendTimeSingleStreamWithHighStartBitrate) { | 
| 563 RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kAbsSendTime, | 636 RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kAbsSendTime, | 
| 564 false, false); | 637 false, false); | 
| 565 } | 638 } | 
| 639 | |
| 640 TEST_F(RampUpTest, TransportSequenceNumberSingleStream) { | |
| 641 RunRampUpTest(1, 0, RtpExtension::kTransportSequenceNumber, false, false); | |
| 642 } | |
| 643 | |
| 644 TEST_F(RampUpTest, TransportSequenceNumberSimulcast) { | |
| 645 RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, false, false); | |
| 646 } | |
| 647 | |
| 648 TEST_F(RampUpTest, TransportSequenceNumberSimulcastWithRtx) { | |
| 649 RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, true, false); | |
| 650 } | |
| 651 | |
| 652 TEST_F(RampUpTest, TransportSequenceNumberSimulcastByRedWithRtx) { | |
| 653 RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, true, true); | |
| 654 } | |
| 655 | |
| 656 TEST_F(RampUpTest, TransportSequenceNumberSingleStreamWithHighStartBitrate) { | |
| 657 RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, | |
| 658 RtpExtension::kTransportSequenceNumber, false, false); | |
| 659 } | |
| 566 } // namespace webrtc | 660 } // namespace webrtc | 
| OLD | NEW |