Index: webrtc/video/end_to_end_tests.cc |
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc |
index 94a87d8864a64b108bfd723aec4e27c16466f953..62bec9149af174c07ae654ab37e610af0faadac9 100644 |
--- a/webrtc/video/end_to_end_tests.cc |
+++ b/webrtc/video/end_to_end_tests.cc |
@@ -76,6 +76,35 @@ class EndToEndTest : public test::CallTest { |
} |
}; |
+ class RequiredTransport : public Transport { |
+ public: |
+ RequiredTransport(bool rtp_required, bool rtcp_required) |
+ : need_rtp_(rtp_required), need_rtcp_(rtcp_required) {} |
+ ~RequiredTransport() { |
+ if (need_rtp_) { |
+ ADD_FAILURE() << "Expected RTP packet not sent."; |
+ } |
+ if (need_rtcp_) { |
+ ADD_FAILURE() << "Expected RTCP packet not sent."; |
+ } |
+ } |
+ |
+ private: |
+ bool SendRtp(const uint8_t* packet, |
+ size_t length, |
+ const PacketOptions& options) override { |
+ need_rtp_ = false; |
+ return true; |
+ } |
+ |
+ bool SendRtcp(const uint8_t* packet, size_t length) override { |
+ need_rtcp_ = false; |
+ return true; |
+ } |
+ bool need_rtp_; |
+ bool need_rtcp_; |
+ }; |
+ |
void DecodesRetransmittedFrame(bool enable_rtx, bool enable_red); |
void ReceivesPliAndRecovers(int rtp_history_ms); |
void RespectsRtcpMode(RtcpMode rtcp_mode); |
@@ -83,6 +112,13 @@ class EndToEndTest : public test::CallTest { |
void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first); |
void TestRtpStatePreservation(bool use_rtx); |
void VerifyHistogramStats(bool use_rtx, bool use_red, bool screenshare); |
+ void VerifyNewVideoSendStreamsRespectNetworkState( |
+ MediaType network_to_bring_down, |
+ VideoEncoder* encoder, |
+ Transport* transport); |
+ void VerifyNewVideoReceiveStreamsRespectNetworkState( |
+ MediaType network_to_bring_down, |
+ Transport* transport); |
}; |
TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) { |
@@ -3219,8 +3255,16 @@ TEST_F(EndToEndTest, RespectsNetworkState) { |
// Wait for packets from both sender/receiver. |
WaitForPacketsOrSilence(false, false); |
+ // Sender-side network down for audio; there should be no effect on video |
+ sender_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkDown); |
+ WaitForPacketsOrSilence(false, false); |
+ |
+ // Receiver-side network down for audio; no change expected |
+ receiver_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkDown); |
+ WaitForPacketsOrSilence(false, false); |
+ |
// Sender-side network down. |
- sender_call_->SignalNetworkState(kNetworkDown); |
+ sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkDown); |
{ |
rtc::CritScope lock(&test_crit_); |
// After network goes down we shouldn't be encoding more frames. |
@@ -3230,7 +3274,13 @@ TEST_F(EndToEndTest, RespectsNetworkState) { |
WaitForPacketsOrSilence(true, false); |
// Receiver-side network down. |
- receiver_call_->SignalNetworkState(kNetworkDown); |
+ receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkDown); |
+ WaitForPacketsOrSilence(true, true); |
+ |
+ // Network up for audio for both sides; video is still not expected to |
+ // start |
+ sender_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp); |
+ receiver_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp); |
WaitForPacketsOrSilence(true, true); |
// Network back up again for both. |
@@ -3240,9 +3290,13 @@ TEST_F(EndToEndTest, RespectsNetworkState) { |
// network. |
sender_state_ = kNetworkUp; |
} |
- sender_call_->SignalNetworkState(kNetworkUp); |
- receiver_call_->SignalNetworkState(kNetworkUp); |
+ sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp); |
+ receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp); |
WaitForPacketsOrSilence(false, false); |
+ |
+ // TODO(skvlad): add tests to verify that the audio streams are stopped |
+ // when the network goes down for audio once the workaround in |
+ // paced_sender.cc is removed. |
} |
int32_t Encode(const VideoFrame& input_image, |
@@ -3293,7 +3347,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) { |
sender_done = true; |
} |
} else { |
- if (sender_rtp_ > initial_sender_rtp) |
+ if (sender_rtp_ > initial_sender_rtp + kNumAcceptedDowntimeRtp) |
sender_done = true; |
} |
if (receiver_down) { |
@@ -3305,7 +3359,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) { |
receiver_done = true; |
} |
} else { |
- if (receiver_rtcp_ > initial_receiver_rtcp) |
+ if (receiver_rtcp_ > initial_receiver_rtcp + kNumAcceptedDowntimeRtcp) |
receiver_done = true; |
} |
} |
@@ -3364,26 +3418,15 @@ TEST_F(EndToEndTest, CallReportsRttForSender) { |
DestroyStreams(); |
} |
-TEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) { |
- class UnusedEncoder : public test::FakeEncoder { |
- public: |
- UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {} |
- int32_t Encode(const VideoFrame& input_image, |
- const CodecSpecificInfo* codec_specific_info, |
- const std::vector<FrameType>* frame_types) override { |
- ADD_FAILURE() << "Unexpected frame encode."; |
- return test::FakeEncoder::Encode( |
- input_image, codec_specific_info, frame_types); |
- } |
- }; |
- |
+void EndToEndTest::VerifyNewVideoSendStreamsRespectNetworkState( |
+ MediaType network_to_bring_down, |
+ VideoEncoder* encoder, |
+ Transport* transport) { |
CreateSenderCall(Call::Config()); |
- sender_call_->SignalNetworkState(kNetworkDown); |
+ sender_call_->SignalChannelNetworkState(network_to_bring_down, kNetworkDown); |
- UnusedTransport transport; |
- CreateSendConfig(1, 0, &transport); |
- UnusedEncoder unused_encoder; |
- video_send_config_.encoder_settings.encoder = &unused_encoder; |
+ CreateSendConfig(1, 0, transport); |
+ video_send_config_.encoder_settings.encoder = encoder; |
CreateVideoStreams(); |
CreateFrameGeneratorCapturer(); |
@@ -3394,15 +3437,17 @@ TEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) { |
DestroyStreams(); |
} |
-TEST_F(EndToEndTest, NewReceiveStreamsRespectNetworkDown) { |
+void EndToEndTest::VerifyNewVideoReceiveStreamsRespectNetworkState( |
+ MediaType network_to_bring_down, |
+ Transport* transport) { |
CreateCalls(Call::Config(), Call::Config()); |
- receiver_call_->SignalNetworkState(kNetworkDown); |
+ receiver_call_->SignalChannelNetworkState(network_to_bring_down, |
+ kNetworkDown); |
test::DirectTransport sender_transport(sender_call_.get()); |
sender_transport.SetReceiver(receiver_call_->Receiver()); |
CreateSendConfig(1, 0, &sender_transport); |
- UnusedTransport transport; |
- CreateMatchingReceiveConfigs(&transport); |
+ CreateMatchingReceiveConfigs(transport); |
CreateVideoStreams(); |
CreateFrameGeneratorCapturer(); |
@@ -3415,6 +3460,63 @@ TEST_F(EndToEndTest, NewReceiveStreamsRespectNetworkDown) { |
DestroyStreams(); |
} |
+TEST_F(EndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) { |
+ class UnusedEncoder : public test::FakeEncoder { |
+ public: |
+ UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {} |
+ int32_t Encode(const VideoFrame& input_image, |
+ const CodecSpecificInfo* codec_specific_info, |
+ const std::vector<FrameType>* frame_types) override { |
+ ADD_FAILURE() << "Unexpected frame encode."; |
+ return test::FakeEncoder::Encode(input_image, codec_specific_info, |
+ frame_types); |
+ } |
+ }; |
+ |
+ UnusedEncoder unused_encoder; |
+ UnusedTransport unused_transport; |
+ VerifyNewVideoSendStreamsRespectNetworkState( |
+ MediaType::VIDEO, &unused_encoder, &unused_transport); |
+} |
+ |
+TEST_F(EndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) { |
+ class RequiredEncoder : public test::FakeEncoder { |
+ public: |
+ RequiredEncoder() |
+ : FakeEncoder(Clock::GetRealTimeClock()), encoded_frame_(false) {} |
+ ~RequiredEncoder() { |
+ if (!encoded_frame_) { |
+ ADD_FAILURE() << "Didn't encode an expected frame"; |
+ } |
+ } |
+ int32_t Encode(const VideoFrame& input_image, |
+ const CodecSpecificInfo* codec_specific_info, |
+ const std::vector<FrameType>* frame_types) override { |
+ encoded_frame_ = true; |
+ return test::FakeEncoder::Encode(input_image, codec_specific_info, |
+ frame_types); |
+ } |
+ |
+ private: |
+ bool encoded_frame_; |
+ }; |
+ |
+ RequiredTransport required_transport(true /*rtp*/, false /*rtcp*/); |
+ RequiredEncoder required_encoder; |
+ VerifyNewVideoSendStreamsRespectNetworkState( |
+ MediaType::AUDIO, &required_encoder, &required_transport); |
+} |
+ |
+TEST_F(EndToEndTest, NewVideoReceiveStreamsRespectVideoNetworkDown) { |
+ UnusedTransport transport; |
+ VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::VIDEO, &transport); |
+} |
+ |
+TEST_F(EndToEndTest, NewVideoReceiveStreamsIgnoreAudioNetworkDown) { |
+ RequiredTransport transport(false /*rtp*/, true /*rtcp*/); |
+ VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport); |
+} |
+ |
void VerifyEmptyNackConfig(const NackConfig& config) { |
EXPECT_EQ(0, config.rtp_history_ms) |
<< "Enabling NACK requires rtcp-fb: nack negotiation."; |