diff options
Diffstat (limited to 'media/engine/webrtc_video_engine_unittest.cc')
-rw-r--r-- | media/engine/webrtc_video_engine_unittest.cc | 346 |
1 files changed, 225 insertions, 121 deletions
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index 4270e274f5..89cc1f4d9f 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -51,17 +51,19 @@ #include "media/engine/fake_webrtc_video_engine.h" #include "media/engine/simulcast.h" #include "media/engine/webrtc_voice_engine.h" +#include "modules/rtp_rtcp/source/rtp_packet.h" #include "rtc_base/arraysize.h" +#include "rtc_base/event.h" #include "rtc_base/experiments/min_video_bitrate_experiment.h" #include "rtc_base/fake_clock.h" #include "rtc_base/gunit.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/time_utils.h" +#include "system_wrappers/include/field_trial.h" #include "test/fake_decoder.h" #include "test/field_trial.h" #include "test/frame_forwarder.h" #include "test/gmock.h" -#include "test/rtp_header_parser.h" using ::testing::_; using ::testing::Contains; @@ -95,6 +97,7 @@ static const uint32_t kSsrcs3[] = {1, 2, 3}; static const uint32_t kRtxSsrcs1[] = {4}; static const uint32_t kFlexfecSsrc = 5; static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE; +static const int64_t kUnsignalledReceiveStreamCooldownMs = 500; constexpr uint32_t kRtpHeaderSize = 12; @@ -1417,6 +1420,10 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { channel_->SetRecvParameters(parameters); } + ~WebRtcVideoChannelEncodedFrameCallbackTest() override { + channel_->SetInterface(nullptr); + } + void DeliverKeyFrame(uint32_t ssrc) { webrtc::RtpPacket packet; packet.SetMarker(true); @@ -1544,7 +1551,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { webrtc::CreateBuiltinVideoDecoderFactory(), field_trials_) {} - virtual void SetUp() { + void SetUp() override { // One testcase calls SetUp in a loop, only create call_ once. if (!call_) { webrtc::Call::Config call_config(&event_log_); @@ -1586,6 +1593,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { // Make the second renderer available for use by a new stream. EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_)); } + // Setup an additional stream just to send video. Defer add recv stream. // This is required if you want to test unsignalled recv of video rtp packets. void SetUpSecondStreamWithNoRecv() { @@ -1604,7 +1612,17 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { EXPECT_TRUE( channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get())); } - virtual void TearDown() { channel_.reset(); } + + void TearDown() override { + channel_->SetInterface(nullptr); + channel_.reset(); + } + + void ResetTest() { + TearDown(); + SetUp(); + } + bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); } bool SetOneCodec(const cricket::VideoCodec& codec) { @@ -1644,20 +1662,13 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { return network_interface_.NumRtpPackets(ssrc); } int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); } - const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) { + rtc::CopyOnWriteBuffer GetRtpPacket(int index) { return network_interface_.GetRtpPacket(index); } - static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) { - webrtc::RTPHeader header; - EXPECT_TRUE(ParseRtpPacket(p, &header)); - return header.payloadType; - } - - static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p, - webrtc::RTPHeader* header) { - std::unique_ptr<webrtc::RtpHeaderParser> parser( - webrtc::RtpHeaderParser::CreateForTest()); - return parser->Parse(p->cdata(), p->size(), header); + static int GetPayloadType(rtc::CopyOnWriteBuffer p) { + webrtc::RtpPacket header; + EXPECT_TRUE(header.Parse(std::move(p))); + return header.PayloadType(); } // Tests that we can send and receive frames. @@ -1668,8 +1679,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { EXPECT_EQ(0, renderer_.num_rendered_frames()); SendFrame(); EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); - std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0)); - EXPECT_EQ(codec.id, GetPayloadType(p.get())); + EXPECT_EQ(codec.id, GetPayloadType(GetRtpPacket(0))); } void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec, @@ -1685,8 +1695,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout); } } - std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0)); - EXPECT_EQ(codec.id, GetPayloadType(p.get())); + EXPECT_EQ(codec.id, GetPayloadType(GetRtpPacket(0))); } cricket::VideoSenderInfo GetSenderStats(size_t i) { @@ -1732,6 +1741,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { webrtc::RtcEventLogNull event_log_; webrtc::FieldTrialBasedConfig field_trials_; + std::unique_ptr<webrtc::test::ScopedFieldTrials> override_field_trials_; std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_; std::unique_ptr<webrtc::Call> call_; std::unique_ptr<webrtc::VideoBitrateAllocatorFactory> @@ -1786,9 +1796,11 @@ TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSize) { // Set field trial to override the default recv buffer size, and then re-run // setup where the interface is created and configured. const int kCustomRecvBufferSize = 123456; - webrtc::test::ScopedFieldTrials field_trial( + RTC_DCHECK(!override_field_trials_); + override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>( "WebRTC-IncreasedReceivebuffers/123456/"); - SetUp(); + + ResetTest(); EXPECT_TRUE(SetOneCodec(DefaultCodec())); EXPECT_TRUE(SetSend(true)); @@ -1802,9 +1814,10 @@ TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSizeWithSuffix) { // Set field trial to override the default recv buffer size, and then re-run // setup where the interface is created and configured. const int kCustomRecvBufferSize = 123456; - webrtc::test::ScopedFieldTrials field_trial( + RTC_DCHECK(!override_field_trials_); + override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>( "WebRTC-IncreasedReceivebuffers/123456_Dogfood/"); - SetUp(); + ResetTest(); EXPECT_TRUE(SetOneCodec(DefaultCodec())); EXPECT_TRUE(SetSend(true)); @@ -1819,24 +1832,50 @@ TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) { // then re-run setup where the interface is created and configured. The // default value should still be used. + const char* prev_field_trials = webrtc::field_trial::GetFieldTrialString(); + + std::string field_trial_string; for (std::string group : {" ", "NotANumber", "-1", "0"}) { - std::string field_trial_string = "WebRTC-IncreasedReceivebuffers/"; - field_trial_string += group; - field_trial_string += "/"; - webrtc::test::ScopedFieldTrials field_trial(field_trial_string); + std::string trial_string = "WebRTC-IncreasedReceivebuffers/"; + trial_string += group; + trial_string += "/"; + + // Dear reader. Sorry for this... it's a bit of a mess. + // TODO(bugs.webrtc.org/12854): This test needs to be rewritten to not use + // ResetTest and changing global field trials in a loop. + TearDown(); + // This is a hack to appease tsan. Because of the way the test is written + // active state within Call, including running task queues may race with + // the test changing the global field trial variable. + // This particular hack, pauses the transport controller TQ while we + // change the field trial. + rtc::TaskQueue* tq = call_->GetTransportControllerSend()->GetWorkerQueue(); + rtc::Event waiting, resume; + tq->PostTask([&waiting, &resume]() { + waiting.Set(); + resume.Wait(rtc::Event::kForever); + }); + + waiting.Wait(rtc::Event::kForever); + field_trial_string = std::move(trial_string); + webrtc::field_trial::InitFieldTrialsFromString(field_trial_string.c_str()); + SetUp(); + resume.Set(); + + // OK, now the test can carry on. EXPECT_TRUE(SetOneCodec(DefaultCodec())); EXPECT_TRUE(SetSend(true)); EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size()); EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size()); } + + webrtc::field_trial::InitFieldTrialsFromString(prev_field_trials); } // Test that stats work properly for a 1-1 call. TEST_F(WebRtcVideoChannelBaseTest, GetStats) { - SetUp(); - const int kDurationSec = 3; const int kFps = 10; SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps); @@ -1893,8 +1932,6 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStats) { // Test that stats work properly for a conf call with multiple recv streams. TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) { - SetUp(); - cricket::FakeVideoRenderer renderer1, renderer2; EXPECT_TRUE(SetOneCodec(DefaultCodec())); cricket::VideoSendParameters parameters; @@ -2023,15 +2060,14 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) { EXPECT_TRUE(SetSend(true)); SendFrame(); EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); - webrtc::RTPHeader header; - std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0)); - EXPECT_TRUE(ParseRtpPacket(p.get(), &header)); - EXPECT_EQ(kSsrc, header.ssrc); + webrtc::RtpPacket header; + EXPECT_TRUE(header.Parse(GetRtpPacket(0))); + EXPECT_EQ(kSsrc, header.Ssrc()); // Packets are being paced out, so these can mismatch between the first and // second call to NumRtpPackets until pending packets are paced out. - EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout); - EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout); + EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.Ssrc()), kTimeout); + EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.Ssrc()), kTimeout); EXPECT_EQ(1, NumSentSsrcs()); EXPECT_EQ(0, NumRtpPackets(kSsrc - 1)); EXPECT_EQ(0, NumRtpBytes(kSsrc - 1)); @@ -2048,14 +2084,13 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) { EXPECT_TRUE(SetSend(true)); EXPECT_TRUE(WaitAndSendFrame(0)); EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); - webrtc::RTPHeader header; - std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0)); - EXPECT_TRUE(ParseRtpPacket(p.get(), &header)); - EXPECT_EQ(999u, header.ssrc); + webrtc::RtpPacket header; + EXPECT_TRUE(header.Parse(GetRtpPacket(0))); + EXPECT_EQ(999u, header.Ssrc()); // Packets are being paced out, so these can mismatch between the first and // second call to NumRtpPackets until pending packets are paced out. - EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout); - EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout); + EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.Ssrc()), kTimeout); + EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.Ssrc()), kTimeout); EXPECT_EQ(1, NumSentSsrcs()); EXPECT_EQ(0, NumRtpPackets(kSsrc)); EXPECT_EQ(0, NumRtpBytes(kSsrc)); @@ -2087,12 +2122,10 @@ TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) { SendFrame(); EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); EXPECT_GT(NumRtpPackets(), 0); - webrtc::RTPHeader header; + webrtc::RtpPacket header; size_t last_packet = NumRtpPackets() - 1; - std::unique_ptr<const rtc::CopyOnWriteBuffer> p( - GetRtpPacket(static_cast<int>(last_packet))); - EXPECT_TRUE(ParseRtpPacket(p.get(), &header)); - EXPECT_EQ(kSsrc, header.ssrc); + EXPECT_TRUE(header.Parse(GetRtpPacket(static_cast<int>(last_packet)))); + EXPECT_EQ(kSsrc, header.Ssrc()); // Remove the send stream that was added during Setup. EXPECT_TRUE(channel_->RemoveSendStream(kSsrc)); @@ -2107,9 +2140,8 @@ TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) { EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout); last_packet = NumRtpPackets() - 1; - p.reset(GetRtpPacket(static_cast<int>(last_packet))); - EXPECT_TRUE(ParseRtpPacket(p.get(), &header)); - EXPECT_EQ(789u, header.ssrc); + EXPECT_TRUE(header.Parse(GetRtpPacket(static_cast<int>(last_packet)))); + EXPECT_EQ(789u, header.Ssrc()); } // Tests the behavior of incoming streams in a conference scenario. @@ -2137,8 +2169,7 @@ TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) { EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight, kTimeout); - std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0)); - EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get())); + EXPECT_EQ(DefaultCodec().id, GetPayloadType(GetRtpPacket(0))); EXPECT_EQ(kVideoWidth, renderer1.width()); EXPECT_EQ(kVideoHeight, renderer1.height()); EXPECT_EQ(kVideoWidth, renderer2.width()); @@ -2513,6 +2544,16 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest { ASSERT_TRUE(channel_->SetSendParameters(send_parameters_)); } + void TearDown() override { + channel_->SetInterface(nullptr); + channel_ = nullptr; + } + + void ResetTest() { + TearDown(); + SetUp(); + } + cricket::VideoCodec GetEngineCodec(const std::string& name) { for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) { if (absl::EqualsIgnoreCase(name, engine_codec.name)) @@ -2525,6 +2566,16 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest { cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); } + // After receciving and processing the packet, enough time is advanced that + // the unsignalled receive stream cooldown is no longer in effect. + void ReceivePacketAndAdvanceTime(rtc::CopyOnWriteBuffer packet, + int64_t packet_time_us) { + channel_->OnPacketReceived(packet, packet_time_us); + rtc::Thread::Current()->ProcessMessages(0); + fake_clock_.AdvanceTime( + webrtc::TimeDelta::Millis(kUnsignalledReceiveStreamCooldownMs)); + } + protected: FakeVideoSendStream* AddSendStream() { return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_)); @@ -2934,7 +2985,7 @@ TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) { } TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) { - webrtc::test::ScopedFieldTrials override_field_trials_( + webrtc::test::ScopedFieldTrials override_field_trials( "WebRTC-FilterAbsSendTimeExtension/Enabled/"); // Enable three redundant extensions. std::vector<std::string> extensions; @@ -3165,7 +3216,7 @@ TEST_F(WebRtcVideoChannelTest, LossNotificationIsEnabledByFieldTrial) { RTC_DCHECK(!override_field_trials_); override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>( "WebRTC-RtcpLossNotification/Enabled/"); - SetUp(); + ResetTest(); TestLossNotificationState(true); } @@ -3173,7 +3224,7 @@ TEST_F(WebRtcVideoChannelTest, LossNotificationCanBeEnabledAndDisabled) { RTC_DCHECK(!override_field_trials_); override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>( "WebRTC-RtcpLossNotification/Enabled/"); - SetUp(); + ResetTest(); AssignDefaultCodec(); VerifyCodecHasDefaultFeedbackParams(default_codec_, true); @@ -4113,10 +4164,10 @@ TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) { const std::vector<FakeFlexfecReceiveStream*>& streams = fake_call_->GetFlexfecReceiveStreams(); ASSERT_EQ(1U, streams.size()); - const FakeFlexfecReceiveStream* stream = streams.front(); + const auto* stream = streams.front(); const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig(); EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type); - EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc); + EXPECT_EQ(kFlexfecSsrc, config.rtp.remote_ssrc); ASSERT_EQ(1U, config.protected_media_ssrcs.size()); EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]); @@ -4229,7 +4280,7 @@ TEST_F(WebRtcVideoChannelFlexfecRecvTest, DuplicateFlexfecCodecIsDropped) { const std::vector<FakeFlexfecReceiveStream*>& streams = fake_call_->GetFlexfecReceiveStreams(); ASSERT_EQ(1U, streams.size()); - const FakeFlexfecReceiveStream* stream = streams.front(); + const auto* stream = streams.front(); const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig(); EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type); } @@ -4305,7 +4356,7 @@ TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) { flexfec_stream->GetConfig(); EXPECT_EQ(GetEngineCodec("flexfec-03").id, flexfec_stream_config.payload_type); - EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc); + EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.rtp.remote_ssrc); ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size()); EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]); const std::vector<FakeVideoReceiveStream*>& video_streams = @@ -4314,17 +4365,17 @@ TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) { const webrtc::VideoReceiveStream::Config& video_stream_config = video_stream->GetConfig(); EXPECT_EQ(video_stream_config.rtp.local_ssrc, - flexfec_stream_config.local_ssrc); + flexfec_stream_config.rtp.local_ssrc); EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode); EXPECT_EQ(video_stream_config.rtcp_send_transport, flexfec_stream_config.rtcp_send_transport); // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a // spec-compliant way. EXPECT_EQ(video_stream_config.rtp.transport_cc, - flexfec_stream_config.transport_cc); + flexfec_stream_config.rtp.transport_cc); EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode); EXPECT_EQ(video_stream_config.rtp.extensions, - flexfec_stream_config.rtp_header_extensions); + flexfec_stream_config.rtp.extensions); } // We should not send FlexFEC, even if we advertise it, unless the right @@ -5075,7 +5126,7 @@ TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) { ASSERT_EQ(1U, streams.size()); const FakeFlexfecReceiveStream* stream = streams.front(); EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type); - EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc); + EXPECT_EQ(kFlexfecSsrc, stream->rtp_config().remote_ssrc); ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size()); EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]); @@ -5128,7 +5179,7 @@ TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front(); EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream_with_recv_params->GetConfig().payload_type); - EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc); + EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().rtp.remote_ssrc); EXPECT_EQ(1U, stream_with_recv_params->GetConfig().protected_media_ssrcs.size()); EXPECT_EQ(kSsrcs1[0], @@ -5142,7 +5193,7 @@ TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, const FakeFlexfecReceiveStream* stream_with_send_params = streams.front(); EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream_with_send_params->GetConfig().payload_type); - EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc); + EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().rtp.remote_ssrc); EXPECT_EQ(1U, stream_with_send_params->GetConfig().protected_media_ssrcs.size()); EXPECT_EQ(kSsrcs1[0], @@ -5248,6 +5299,7 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) { channel->SetInterface(network_interface.get()); // Default value when DSCP is disabled should be DSCP_DEFAULT. EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp()); + channel->SetInterface(nullptr); // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set // through rtp parameters. @@ -5277,6 +5329,7 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) { EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get()) ->SendRtcp(kData, sizeof(kData))); EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp); + channel->SetInterface(nullptr); // Verify that setting the option to false resets the // DiffServCodePoint. @@ -5287,6 +5340,7 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) { video_bitrate_allocator_factory_.get()))); channel->SetInterface(network_interface.get()); EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp()); + channel->SetInterface(nullptr); } // This test verifies that the RTCP reduced size mode is properly applied to @@ -5561,9 +5615,11 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) { substream.rtcp_packet_type_counts.fir_packets = 14; substream.rtcp_packet_type_counts.nack_packets = 15; substream.rtcp_packet_type_counts.pli_packets = 16; - substream.rtcp_stats.packets_lost = 17; - substream.rtcp_stats.fraction_lost = 18; + webrtc::RTCPReportBlock report_block; + report_block.packets_lost = 17; + report_block.fraction_lost = 18; webrtc::ReportBlockData report_block_data; + report_block_data.SetReportBlock(report_block, 0); report_block_data.AddRoundTripTimeSample(19); substream.report_block_data = report_block_data; substream.encode_frame_rate = 20.0; @@ -5597,9 +5653,12 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) { static_cast<int>(2 * substream.rtp_stats.transmitted.packets)); EXPECT_EQ(sender.retransmitted_packets_sent, 2u * substream.rtp_stats.retransmitted.packets); - EXPECT_EQ(sender.packets_lost, 2 * substream.rtcp_stats.packets_lost); + EXPECT_EQ(sender.packets_lost, + 2 * substream.report_block_data->report_block().packets_lost); EXPECT_EQ(sender.fraction_lost, - static_cast<float>(substream.rtcp_stats.fraction_lost) / (1 << 8)); + static_cast<float>( + substream.report_block_data->report_block().fraction_lost) / + (1 << 8)); EXPECT_EQ(sender.rtt_ms, 0); EXPECT_EQ(sender.codec_name, DefaultCodec().name); EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id); @@ -5679,9 +5738,11 @@ TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) { substream.rtcp_packet_type_counts.fir_packets = 14; substream.rtcp_packet_type_counts.nack_packets = 15; substream.rtcp_packet_type_counts.pli_packets = 16; - substream.rtcp_stats.packets_lost = 17; - substream.rtcp_stats.fraction_lost = 18; + webrtc::RTCPReportBlock report_block; + report_block.packets_lost = 17; + report_block.fraction_lost = 18; webrtc::ReportBlockData report_block_data; + report_block_data.SetReportBlock(report_block, 0); report_block_data.AddRoundTripTimeSample(19); substream.report_block_data = report_block_data; substream.encode_frame_rate = 20.0; @@ -5715,9 +5776,12 @@ TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) { static_cast<int>(substream.rtp_stats.transmitted.packets)); EXPECT_EQ(sender.retransmitted_packets_sent, substream.rtp_stats.retransmitted.packets); - EXPECT_EQ(sender.packets_lost, substream.rtcp_stats.packets_lost); + EXPECT_EQ(sender.packets_lost, + substream.report_block_data->report_block().packets_lost); EXPECT_EQ(sender.fraction_lost, - static_cast<float>(substream.rtcp_stats.fraction_lost) / (1 << 8)); + static_cast<float>( + substream.report_block_data->report_block().fraction_lost) / + (1 << 8)); EXPECT_EQ(sender.rtt_ms, 0); EXPECT_EQ(sender.codec_name, DefaultCodec().name); EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id); @@ -6244,8 +6308,7 @@ TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], ssrcs[0]); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()) << "No default receive stream created."; @@ -6406,8 +6469,7 @@ TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); // The stream should now be created with the appropriate sync label. EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); @@ -6422,16 +6484,14 @@ TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) { // Until the demuxer criteria has been updated, we ignore in-flight ssrcs of // the recently removed unsignaled receive stream. - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size()); // After the demuxer criteria has been updated, we should proceed to create // unsignalled receive streams. This time when a default video receive stream // is created it won't have a sync_group. channel_->OnDemuxerCriteriaUpdateComplete(); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); EXPECT_TRUE( fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty()); @@ -6448,8 +6508,7 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); // Default receive stream created. const auto& receivers1 = fake_call_->GetVideoReceiveStreams(); @@ -6499,7 +6558,7 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc1); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } { // Receive a packet for kSsrc2. @@ -6508,9 +6567,8 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc2); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); // No unsignaled ssrc for kSsrc2 should have been created, but kSsrc1 should // arrive since it already has a stream. @@ -6532,7 +6590,7 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc1); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } { // Receive a packet for kSsrc2. @@ -6541,9 +6599,8 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc2); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); // An unsignalled ssrc for kSsrc2 should be created and the packet counter // should increase for both ssrcs. @@ -6584,7 +6641,7 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc1); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } { // Receive a packet for kSsrc2. @@ -6593,9 +6650,8 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc2); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); // No unsignaled ssrc for kSsrc1 should have been created, but the packet // count for kSsrc2 should increase. @@ -6616,7 +6672,7 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc1); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } { // Receive a packet for kSsrc2. @@ -6625,9 +6681,8 @@ TEST_F(WebRtcVideoChannelTest, memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc2); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); // An unsignalled ssrc for kSsrc1 should be created and the packet counter // should increase for both ssrcs. @@ -6664,9 +6719,8 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 1u); // Signal that the demuxer knows about the first update: the removal. @@ -6681,9 +6735,8 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 2u); // Remove the kSsrc again while previous demuxer updates are still pending. @@ -6699,9 +6752,8 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 0u); EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 2u); @@ -6717,9 +6769,8 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); } - rtc::Thread::Current()->ProcessMessages(0); EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 0u); EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 2u); @@ -6735,11 +6786,72 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); + } + EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u); + EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 3u); +} + +TEST_F(WebRtcVideoChannelTest, UnsignalledSsrcHasACooldown) { + const uint32_t kSsrc1 = 1; + const uint32_t kSsrc2 = 2; + + // Send packets for kSsrc1, creating an unsignalled receive stream. + { + // Receive a packet for kSsrc1. + const size_t kDataLength = 12; + uint8_t data[kDataLength]; + memset(data, 0, sizeof(data)); + rtc::SetBE32(&data[8], kSsrc1); + rtc::CopyOnWriteBuffer packet(data, kDataLength); channel_->OnPacketReceived(packet, /* packet_time_us */ -1); } rtc::Thread::Current()->ProcessMessages(0); + fake_clock_.AdvanceTime( + webrtc::TimeDelta::Millis(kUnsignalledReceiveStreamCooldownMs - 1)); + + // We now have an unsignalled receive stream for kSsrc1. EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u); - EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 3u); + EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u); + EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 0u); + + { + // Receive a packet for kSsrc2. + const size_t kDataLength = 12; + uint8_t data[kDataLength]; + memset(data, 0, sizeof(data)); + rtc::SetBE32(&data[8], kSsrc2); + rtc::CopyOnWriteBuffer packet(data, kDataLength); + channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + } + rtc::Thread::Current()->ProcessMessages(0); + + // Not enough time has passed to replace the unsignalled receive stream, so + // the kSsrc2 should be ignored. + EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u); + EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u); + EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 0u); + + // After 500 ms, kSsrc2 should trigger a new unsignalled receive stream that + // replaces the old one. + fake_clock_.AdvanceTime(webrtc::TimeDelta::Millis(1)); + { + // Receive a packet for kSsrc2. + const size_t kDataLength = 12; + uint8_t data[kDataLength]; + memset(data, 0, sizeof(data)); + rtc::SetBE32(&data[8], kSsrc2); + rtc::CopyOnWriteBuffer packet(data, kDataLength); + channel_->OnPacketReceived(packet, /* packet_time_us */ -1); + } + rtc::Thread::Current()->ProcessMessages(0); + + // The old unsignalled receive stream was destroyed and replaced, so we still + // only have one unsignalled receive stream. But tha packet counter for kSsrc2 + // has now increased. + EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u); + EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u); + EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 1u); } // Test BaseMinimumPlayoutDelayMs on receive streams. @@ -6775,8 +6887,7 @@ TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) { memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc); EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200); @@ -6813,8 +6924,7 @@ void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket( rtc::Set8(data, 1, payload_type); rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc); rtc::CopyOnWriteBuffer packet(data, kDataLength); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); if (expect_created_receive_stream) { EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()) @@ -6901,8 +7011,7 @@ TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) { rtpHeader.ssrc = kIncomingUnsignalledSsrc + 1; cricket::SetRtpHeader(data, sizeof(data), rtpHeader); rtc::CopyOnWriteBuffer packet(data, sizeof(data)); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); // VP8 packet should create default receive stream. ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0]; @@ -6923,8 +7032,7 @@ TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) { rtpHeader.ssrc = kIncomingUnsignalledSsrc + 2; cricket::SetRtpHeader(data, sizeof(data), rtpHeader); rtc::CopyOnWriteBuffer packet2(data, sizeof(data)); - channel_->OnPacketReceived(packet2, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet2, /* packet_time_us */ -1); // VP9 packet should replace the default receive SSRC. ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); recv_stream = fake_call_->GetVideoReceiveStreams()[0]; @@ -6946,8 +7054,7 @@ TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) { rtpHeader.ssrc = kIncomingUnsignalledSsrc + 3; cricket::SetRtpHeader(data, sizeof(data), rtpHeader); rtc::CopyOnWriteBuffer packet3(data, sizeof(data)); - channel_->OnPacketReceived(packet3, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet3, /* packet_time_us */ -1); // H264 packet should replace the default receive SSRC. ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); recv_stream = fake_call_->GetVideoReceiveStreams()[0]; @@ -6986,8 +7093,7 @@ TEST_F(WebRtcVideoChannelTest, rtp_header.ssrc = kSsrcs3[0]; cricket::SetRtpHeader(data, sizeof(data), rtp_header); rtc::CopyOnWriteBuffer packet(data, sizeof(data)); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); // Default receive stream should be created. ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); FakeVideoReceiveStream* recv_stream0 = @@ -7005,8 +7111,7 @@ TEST_F(WebRtcVideoChannelTest, rtp_header.ssrc = kSsrcs3[1]; cricket::SetRtpHeader(data, sizeof(data), rtp_header); packet.SetData(data, sizeof(data)); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); // New default receive stream should be created, but old stream should remain. ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size()); EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]); @@ -8619,8 +8724,7 @@ TEST_F(WebRtcVideoChannelTest, rtpHeader.ssrc = kIncomingUnsignalledSsrc; cricket::SetRtpHeader(data, sizeof(data), rtpHeader); rtc::CopyOnWriteBuffer packet(data, sizeof(data)); - channel_->OnPacketReceived(packet, /* packet_time_us */ -1); - rtc::Thread::Current()->ProcessMessages(0); + ReceivePacketAndAdvanceTime(packet, /* packet_time_us */ -1); // The |ssrc| member should still be unset. rtp_parameters = channel_->GetDefaultRtpReceiveParameters(); |