Start probes only after network is connected.

Previously ProbeController was starting probing as soon as SetBitrates()
is called. As result these probes would often timeout while connection
is being established. Now ProbeController receives notifications about
network route changes. This allows to start probing only when transport
is connected. This also makes it possible to restart probing whenever
transport route changes (will be done in a separate change).

BUG=webrtc:6332
R=honghaiz@webrtc.org, philipel@webrtc.org, stefan@webrtc.org

Review URL: https://codereview.webrtc.org/2458863002 .

Committed: https://crrev.com/5c99c76255ee7bface3c742c25fb5617748ac86e
Cr-Original-Commit-Position: refs/heads/master@{#15094}
Cr-Commit-Position: refs/heads/master@{#15204}
This commit is contained in:
Sergey Ulanov 2016-11-22 16:08:30 -08:00
parent 1c062bf0af
commit e2b1501101
12 changed files with 98 additions and 33 deletions

View File

@ -48,7 +48,7 @@ double MediaRatio(uint32_t allocated_bitrate, uint32_t protection_bitrate) {
BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer)
: limit_observer_(limit_observer),
bitrate_observer_configs_(),
last_bitrate_bps_(kDefaultBitrateBps),
last_bitrate_bps_(0),
last_non_zero_bitrate_bps_(kDefaultBitrateBps),
last_fraction_loss_(0),
last_rtt_(0),

View File

@ -252,8 +252,8 @@ Call::Call(const Call::Config& config)
call_stats_(new CallStats(clock_)),
bitrate_allocator_(new BitrateAllocator(this)),
config_(config),
audio_network_state_(kNetworkUp),
video_network_state_(kNetworkUp),
audio_network_state_(kNetworkDown),
video_network_state_(kNetworkDown),
receive_crit_(RWLockWrapper::CreateRWLock()),
send_crit_(RWLockWrapper::CreateRWLock()),
event_log_(config.event_log),
@ -284,6 +284,7 @@ Call::Call(const Call::Config& config)
Trace::CreateTrace();
call_stats_->RegisterStatsObserver(congestion_controller_.get());
congestion_controller_->SignalNetworkState(kNetworkDown);
congestion_controller_->SetBweBitrates(
config_.bitrate_config.min_bitrate_bps,
config_.bitrate_config.start_bitrate_bps,

View File

@ -84,6 +84,7 @@ class VideoMediaChannelTest : public testing::Test,
engine_.Init();
channel_.reset(engine_.CreateChannel(call_.get(), cricket::MediaConfig(),
cricket::VideoOptions()));
channel_->OnReadyToSend(true);
EXPECT_TRUE(channel_.get() != NULL);
network_interface_.SetDestination(channel_.get());
channel_->SetInterface(&network_interface_);

View File

@ -353,6 +353,7 @@ TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
std::unique_ptr<VideoMediaChannel> channel(
SetUpForExternalEncoderFactory(&encoder_factory));
channel->OnReadyToSend(true);
EXPECT_TRUE(
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
@ -916,6 +917,7 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
engine_.Init();
channel_.reset(
engine_.CreateChannel(fake_call_.get(), MediaConfig(), VideoOptions()));
channel_->OnReadyToSend(true);
last_ssrc_ = 123;
send_parameters_.codecs = engine_.codecs();
recv_parameters_.codecs = engine_.codecs();
@ -1731,6 +1733,7 @@ TEST_F(WebRtcVideoChannel2Test, SetMediaConfigSuspendBelowMinBitrate) {
channel_.reset(
engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
channel_->OnReadyToSend(true);
channel_->SetSendParameters(send_parameters_);
@ -1740,6 +1743,7 @@ TEST_F(WebRtcVideoChannel2Test, SetMediaConfigSuspendBelowMinBitrate) {
media_config.video.suspend_below_min_bitrate = false;
channel_.reset(
engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
channel_->OnReadyToSend(true);
channel_->SetSendParameters(send_parameters_);
@ -2024,6 +2028,7 @@ TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) {
MediaConfig media_config = MediaConfig();
channel_.reset(
engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
channel_->OnReadyToSend(true);
ASSERT_TRUE(channel_->SetSendParameters(parameters));
AddSendStream();
@ -2098,6 +2103,7 @@ TEST_F(WebRtcVideoChannel2Test, PreviousAdaptationDoesNotApplyToScreenshare) {
MediaConfig media_config = MediaConfig();
channel_.reset(
engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
channel_->OnReadyToSend(true);
ASSERT_TRUE(channel_->SetSendParameters(parameters));
AddSendStream();
@ -2165,6 +2171,7 @@ void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse,
}
channel_.reset(
engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
channel_->OnReadyToSend(true);
EXPECT_TRUE(channel_->SetSendParameters(parameters));
@ -3865,6 +3872,7 @@ class WebRtcVideoChannel2SimulcastTest : public testing::Test {
engine_.Init();
channel_.reset(
engine_.CreateChannel(&fake_call_, MediaConfig(), VideoOptions()));
channel_->OnReadyToSend(true);
last_ssrc_ = 123;
}

View File

@ -297,6 +297,7 @@ void CongestionController::SignalNetworkState(NetworkState state) {
rtc::CritScope cs(&critsect_);
network_state_ = state;
}
probe_controller_->OnNetworkStateChanged(state);
MaybeTriggerOnNetworkChanged();
}

View File

@ -46,10 +46,12 @@ constexpr int kAlrProbingIntervalLimitMs = 5000;
ProbeController::ProbeController(PacedSender* pacer, Clock* clock)
: pacer_(pacer),
clock_(clock),
network_state_(kNetworkUp),
state_(State::kInit),
min_bitrate_to_probe_further_bps_(kExponentialProbingDisabled),
time_last_probing_initiated_ms_(0),
estimated_bitrate_bps_(0),
start_bitrate_bps_(0),
max_bitrate_bps_(0),
last_alr_probing_time_(clock_->TimeInMilliseconds()) {}
@ -57,30 +59,54 @@ void ProbeController::SetBitrates(int min_bitrate_bps,
int start_bitrate_bps,
int max_bitrate_bps) {
rtc::CritScope cs(&critsect_);
if (state_ == State::kInit) {
// When probing at 1.8 Mbps ( 6x 300), this represents a threshold of
// 1.2 Mbps to continue probing.
InitiateProbing({3 * start_bitrate_bps, 6 * start_bitrate_bps},
4 * start_bitrate_bps);
if (start_bitrate_bps > 0) {
start_bitrate_bps_ = start_bitrate_bps;
} else if (start_bitrate_bps_ == 0) {
start_bitrate_bps_ = min_bitrate_bps;
}
int old_max_bitrate_bps = max_bitrate_bps_;
max_bitrate_bps_ = max_bitrate_bps;
// Only do probing if:
// we are mid-call, which we consider to be if
// exponential probing is not active and
// |estimated_bitrate_bps_| is valid (> 0) and
// the current bitrate is lower than the new |max_bitrate_bps|, and
// |max_bitrate_bps_| was increased.
if (state_ != State::kWaitingForProbingResult &&
estimated_bitrate_bps_ != 0 &&
estimated_bitrate_bps_ < old_max_bitrate_bps &&
max_bitrate_bps_ > old_max_bitrate_bps) {
InitiateProbing({max_bitrate_bps}, kExponentialProbingDisabled);
switch (state_) {
case State::kInit:
if (network_state_ == kNetworkUp)
InitiateExponentialProbing();
break;
case State::kWaitingForProbingResult:
break;
case State::kProbingComplete:
// Initiate probing when |max_bitrate_| was increased mid-call.
if (estimated_bitrate_bps_ != 0 &&
estimated_bitrate_bps_ < old_max_bitrate_bps &&
max_bitrate_bps_ > old_max_bitrate_bps) {
InitiateProbing({max_bitrate_bps}, kExponentialProbingDisabled);
}
break;
}
}
void ProbeController::OnNetworkStateChanged(NetworkState network_state) {
rtc::CritScope cs(&critsect_);
network_state_ = network_state;
if (network_state_ == kNetworkUp && state_ == State::kInit)
InitiateExponentialProbing();
}
void ProbeController::InitiateExponentialProbing() {
RTC_DCHECK(network_state_ == kNetworkUp);
RTC_DCHECK(state_ == State::kInit);
RTC_DCHECK_GT(start_bitrate_bps_, 0);
// When probing at 1.8 Mbps ( 6x 300), this represents a threshold of
// 1.2 Mbps to continue probing.
InitiateProbing({3 * start_bitrate_bps_, 6 * start_bitrate_bps_},
4 * start_bitrate_bps_);
}
void ProbeController::SetEstimatedBitrate(int bitrate_bps) {
rtc::CritScope cs(&critsect_);
if (state_ == State::kWaitingForProbingResult) {

View File

@ -31,12 +31,12 @@ class ProbeController {
void SetBitrates(int min_bitrate_bps,
int start_bitrate_bps,
int max_bitrate_bps);
void OnNetworkStateChanged(NetworkState state);
void SetEstimatedBitrate(int bitrate_bps);
private:
void InitiateProbing(std::initializer_list<int> bitrates_to_probe,
int min_bitrate_to_probe_further_bps)
EXCLUSIVE_LOCKS_REQUIRED(critsect_);
enum class State {
// Initial state where no probing has been triggered yet.
kInit,
@ -45,13 +45,21 @@ class ProbeController {
// Probing is complete.
kProbingComplete,
};
void InitiateExponentialProbing() EXCLUSIVE_LOCKS_REQUIRED(critsect_);
void InitiateProbing(std::initializer_list<int> bitrates_to_probe,
int min_bitrate_to_probe_further_bps)
EXCLUSIVE_LOCKS_REQUIRED(critsect_);
rtc::CriticalSection critsect_;
PacedSender* const pacer_;
Clock* const clock_;
NetworkState network_state_ GUARDED_BY(critsect_);
State state_ GUARDED_BY(critsect_);
int min_bitrate_to_probe_further_bps_ GUARDED_BY(critsect_);
int64_t time_last_probing_initiated_ms_ GUARDED_BY(critsect_);
int estimated_bitrate_bps_ GUARDED_BY(critsect_);
int start_bitrate_bps_ GUARDED_BY(critsect_);
int max_bitrate_bps_ GUARDED_BY(critsect_);
int64_t last_alr_probing_time_ GUARDED_BY(critsect_);

View File

@ -51,6 +51,17 @@ TEST_F(ProbeControllerTest, InitiatesProbingAtStart) {
kMaxBitrateBps);
}
TEST_F(ProbeControllerTest, ProbeOnlyWhenNetworkIsUp) {
probe_controller_->OnNetworkStateChanged(kNetworkDown);
EXPECT_CALL(pacer_, CreateProbeCluster(_, _)).Times(0);
probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
kMaxBitrateBps);
testing::Mock::VerifyAndClearExpectations(&pacer_);
EXPECT_CALL(pacer_, CreateProbeCluster(_, _)).Times(AtLeast(2));
probe_controller_->OnNetworkStateChanged(kNetworkUp);
}
TEST_F(ProbeControllerTest, InitiatesProbingOnMaxBitrateIncrease) {
EXPECT_CALL(pacer_, CreateProbeCluster(_, _)).Times(AtLeast(2));
probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,

View File

@ -75,6 +75,10 @@ void CallTest::RunBaseTest(BaseTest* test) {
if (test->ShouldCreateReceivers()) {
send_transport_->SetReceiver(receiver_call_->Receiver());
receive_transport_->SetReceiver(sender_call_->Receiver());
if (num_video_streams_ > 0)
receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
if (num_audio_streams_ > 0)
receiver_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
} else {
// Sender-only call delivers to itself.
send_transport_->SetReceiver(sender_call_->Receiver());

View File

@ -28,6 +28,10 @@ DirectTransport::DirectTransport(const FakeNetworkPipe::Config& config,
shutting_down_(false),
fake_network_(clock_, config) {
thread_.Start();
if (send_call_) {
send_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
send_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
}
}
DirectTransport::~DirectTransport() { StopSending(); }

View File

@ -122,11 +122,11 @@ class EndToEndTest : public test::CallTest {
void TestRtpStatePreservation(bool use_rtx, bool provoke_rtcpsr_before_rtp);
void VerifyHistogramStats(bool use_rtx, bool use_red, bool screenshare);
void VerifyNewVideoSendStreamsRespectNetworkState(
MediaType network_to_bring_down,
MediaType network_to_bring_up,
VideoEncoder* encoder,
Transport* transport);
void VerifyNewVideoReceiveStreamsRespectNetworkState(
MediaType network_to_bring_down,
MediaType network_to_bring_up,
Transport* transport);
};
@ -3671,11 +3671,11 @@ TEST_F(EndToEndTest, CallReportsRttForSender) {
}
void EndToEndTest::VerifyNewVideoSendStreamsRespectNetworkState(
MediaType network_to_bring_down,
MediaType network_to_bring_up,
VideoEncoder* encoder,
Transport* transport) {
CreateSenderCall(Call::Config(&event_log_));
sender_call_->SignalChannelNetworkState(network_to_bring_down, kNetworkDown);
sender_call_->SignalChannelNetworkState(network_to_bring_up, kNetworkUp);
CreateSendConfig(1, 0, 0, transport);
video_send_config_.encoder_settings.encoder = encoder;
@ -3691,12 +3691,11 @@ void EndToEndTest::VerifyNewVideoSendStreamsRespectNetworkState(
}
void EndToEndTest::VerifyNewVideoReceiveStreamsRespectNetworkState(
MediaType network_to_bring_down,
MediaType network_to_bring_up,
Transport* transport) {
Call::Config config(&event_log_);
CreateCalls(config, config);
receiver_call_->SignalChannelNetworkState(network_to_bring_down,
kNetworkDown);
receiver_call_->SignalChannelNetworkState(network_to_bring_up, kNetworkUp);
test::DirectTransport sender_transport(sender_call_.get());
sender_transport.SetReceiver(receiver_call_->Receiver());
@ -3738,7 +3737,7 @@ TEST_F(EndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) {
UnusedEncoder unused_encoder;
UnusedTransport unused_transport;
VerifyNewVideoSendStreamsRespectNetworkState(
MediaType::VIDEO, &unused_encoder, &unused_transport);
MediaType::AUDIO, &unused_encoder, &unused_transport);
}
TEST_F(EndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) {
@ -3766,17 +3765,17 @@ TEST_F(EndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) {
RequiredTransport required_transport(true /*rtp*/, false /*rtcp*/);
RequiredEncoder required_encoder;
VerifyNewVideoSendStreamsRespectNetworkState(
MediaType::AUDIO, &required_encoder, &required_transport);
MediaType::VIDEO, &required_encoder, &required_transport);
}
TEST_F(EndToEndTest, NewVideoReceiveStreamsRespectVideoNetworkDown) {
UnusedTransport transport;
VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::VIDEO, &transport);
VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport);
}
TEST_F(EndToEndTest, NewVideoReceiveStreamsIgnoreAudioNetworkDown) {
RequiredTransport transport(false /*rtp*/, true /*rtcp*/);
VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport);
VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::VIDEO, &transport);
}
void VerifyEmptyNackConfig(const NackConfig& config) {

View File

@ -1836,6 +1836,8 @@ TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
test::NullTransport transport;
CreateSendConfig(1, 0, 0, &transport);
sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
StartStopBitrateObserver encoder;
video_send_config_.encoder_settings.encoder = &encoder;
video_send_config_.encoder_settings.internal_source = true;