diff options
Diffstat (limited to 'webrtc/video/end_to_end_tests.cc')
-rw-r--r-- | webrtc/video/end_to_end_tests.cc | 1000 |
1 files changed, 597 insertions, 403 deletions
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index e86f560cfd..48dc3e8bbd 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -24,15 +24,13 @@ #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" -#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h" +#include "webrtc/modules/video_coding/include/video_coding_defines.h" #include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" #include "webrtc/system_wrappers/include/metrics.h" #include "webrtc/system_wrappers/include/sleep.h" #include "webrtc/test/call_test.h" #include "webrtc/test/direct_transport.h" #include "webrtc/test/encoder_settings.h" -#include "webrtc/test/fake_audio_device.h" #include "webrtc/test/fake_decoder.h" #include "webrtc/test/fake_encoder.h" #include "webrtc/test/frame_generator.h" @@ -42,21 +40,20 @@ #include "webrtc/test/rtcp_packet_parser.h" #include "webrtc/test/rtp_rtcp_observer.h" #include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" #include "webrtc/test/testsupport/perf_test.h" #include "webrtc/video_encoder.h" namespace webrtc { -static const unsigned long kSilenceTimeoutMs = 2000; +static const int kSilenceTimeoutMs = 2000; class EndToEndTest : public test::CallTest { public: EndToEndTest() {} virtual ~EndToEndTest() { - EXPECT_EQ(nullptr, send_stream_); - EXPECT_TRUE(receive_streams_.empty()); + EXPECT_EQ(nullptr, video_send_stream_); + EXPECT_TRUE(video_receive_streams_.empty()); } protected: @@ -81,20 +78,20 @@ class EndToEndTest : public test::CallTest { void TestXrReceiverReferenceTimeReport(bool enable_rrtr); void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first); void TestRtpStatePreservation(bool use_rtx); - void VerifyHistogramStats(bool use_rtx, bool use_red); + void VerifyHistogramStats(bool use_rtx, bool use_red, bool screenshare); }; TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) { CreateCalls(Call::Config(), Call::Config()); test::NullTransport transport; - CreateSendConfig(1, &transport); + CreateSendConfig(1, 0, &transport); CreateMatchingReceiveConfigs(&transport); - CreateStreams(); + CreateVideoStreams(); - receive_streams_[0]->Start(); - receive_streams_[0]->Start(); + video_receive_streams_[0]->Start(); + video_receive_streams_[0]->Start(); DestroyStreams(); } @@ -103,13 +100,13 @@ TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) { CreateCalls(Call::Config(), Call::Config()); test::NullTransport transport; - CreateSendConfig(1, &transport); + CreateSendConfig(1, 0, &transport); CreateMatchingReceiveConfigs(&transport); - CreateStreams(); + CreateVideoStreams(); - receive_streams_[0]->Stop(); - receive_streams_[0]->Stop(); + video_receive_streams_[0]->Stop(); + video_receive_streams_[0]->Stop(); DestroyStreams(); } @@ -124,33 +121,33 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) { class Renderer : public VideoRenderer { public: - Renderer() : event_(EventWrapper::Create()) {} + Renderer() : event_(false, false) {} void RenderFrame(const VideoFrame& video_frame, int /*time_to_render_ms*/) override { - event_->Set(); + event_.Set(); } bool IsTextureSupported() const override { return false; } - EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } + bool Wait() { return event_.Wait(kDefaultTimeoutMs); } - rtc::scoped_ptr<EventWrapper> event_; + rtc::Event event_; } renderer; class TestFrameCallback : public I420FrameCallback { public: - TestFrameCallback() : event_(EventWrapper::Create()) {} + TestFrameCallback() : event_(false, false) {} - EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } + bool Wait() { return event_.Wait(kDefaultTimeoutMs); } private: void FrameCallback(VideoFrame* frame) override { SleepMs(kDelayRenderCallbackMs); - event_->Set(); + event_.Set(); } - rtc::scoped_ptr<EventWrapper> event_; + rtc::Event event_; }; CreateCalls(Call::Config(), Call::Config()); @@ -160,24 +157,25 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateSendConfig(1, &sender_transport); + CreateSendConfig(1, 0, &sender_transport); CreateMatchingReceiveConfigs(&receiver_transport); TestFrameCallback pre_render_callback; - receive_configs_[0].pre_render_callback = &pre_render_callback; - receive_configs_[0].renderer = &renderer; + video_receive_configs_[0].pre_render_callback = &pre_render_callback; + video_receive_configs_[0].renderer = &renderer; - CreateStreams(); + CreateVideoStreams(); Start(); // Create frames that are smaller than the send width/height, this is done to // check that the callbacks are done after processing video. rtc::scoped_ptr<test::FrameGenerator> frame_generator( test::FrameGenerator::CreateChromaGenerator(kWidth, kHeight)); - send_stream_->Input()->IncomingCapturedFrame(*frame_generator->NextFrame()); - EXPECT_EQ(kEventSignaled, pre_render_callback.Wait()) + video_send_stream_->Input()->IncomingCapturedFrame( + *frame_generator->NextFrame()); + EXPECT_TRUE(pre_render_callback.Wait()) << "Timed out while waiting for pre-render callback."; - EXPECT_EQ(kEventSignaled, renderer.Wait()) + EXPECT_TRUE(renderer.Wait()) << "Timed out while waiting for the frame to render."; Stop(); @@ -191,17 +189,17 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) { TEST_F(EndToEndTest, TransmitsFirstFrame) { class Renderer : public VideoRenderer { public: - Renderer() : event_(EventWrapper::Create()) {} + Renderer() : event_(false, false) {} void RenderFrame(const VideoFrame& video_frame, int /*time_to_render_ms*/) override { - event_->Set(); + event_.Set(); } bool IsTextureSupported() const override { return false; } - EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } + bool Wait() { return event_.Wait(kDefaultTimeoutMs); } - rtc::scoped_ptr<EventWrapper> event_; + rtc::Event event_; } renderer; CreateCalls(Call::Config(), Call::Config()); @@ -211,19 +209,21 @@ TEST_F(EndToEndTest, TransmitsFirstFrame) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateSendConfig(1, &sender_transport); + CreateSendConfig(1, 0, &sender_transport); CreateMatchingReceiveConfigs(&receiver_transport); - receive_configs_[0].renderer = &renderer; + video_receive_configs_[0].renderer = &renderer; - CreateStreams(); + CreateVideoStreams(); Start(); rtc::scoped_ptr<test::FrameGenerator> frame_generator( test::FrameGenerator::CreateChromaGenerator( - encoder_config_.streams[0].width, encoder_config_.streams[0].height)); - send_stream_->Input()->IncomingCapturedFrame(*frame_generator->NextFrame()); + video_encoder_config_.streams[0].width, + video_encoder_config_.streams[0].height)); + video_send_stream_->Input()->IncomingCapturedFrame( + *frame_generator->NextFrame()); - EXPECT_EQ(kEventSignaled, renderer.Wait()) + EXPECT_TRUE(renderer.Wait()) << "Timed out while waiting for the frame to render."; Stop(); @@ -244,13 +244,14 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9) { frame_counter_(0) {} void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while waiting for enough frames to be decoded."; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->encoder_settings.encoder = encoder_.get(); send_config->encoder_settings.payload_name = "VP9"; send_config->encoder_settings.payload_type = 124; @@ -271,7 +272,7 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9) { int time_to_render_ms) override { const int kRequiredFrames = 500; if (++frame_counter_ == kRequiredFrames) - observation_complete_->Set(); + observation_complete_.Set(); } bool IsTextureSupported() const override { return false; } @@ -282,7 +283,7 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9) { int frame_counter_; } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, SendsAndReceivesH264) { @@ -294,18 +295,19 @@ TEST_F(EndToEndTest, SendsAndReceivesH264) { frame_counter_(0) {} void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while waiting for enough frames to be decoded."; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->rtp.nack.rtp_history_ms = (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; send_config->encoder_settings.encoder = &fake_encoder_; send_config->encoder_settings.payload_name = "H264"; - send_config->encoder_settings.payload_type = kFakeSendPayloadType; + send_config->encoder_settings.payload_type = kFakeVideoSendPayloadType; encoder_config->streams[0].min_bitrate_bps = 50000; encoder_config->streams[0].target_bitrate_bps = encoder_config->streams[0].max_bitrate_bps = 2000000; @@ -323,7 +325,7 @@ TEST_F(EndToEndTest, SendsAndReceivesH264) { int time_to_render_ms) override { const int kRequiredFrames = 500; if (++frame_counter_ == kRequiredFrames) - observation_complete_->Set(); + observation_complete_.Set(); } bool IsTextureSupported() const override { return false; } @@ -334,7 +336,7 @@ TEST_F(EndToEndTest, SendsAndReceivesH264) { int frame_counter_; } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) { @@ -350,19 +352,19 @@ TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) { ssrc |= static_cast<uint32_t>(packet[5]) << 16; ssrc |= static_cast<uint32_t>(packet[6]) << 8; ssrc |= static_cast<uint32_t>(packet[7]) << 0; - EXPECT_EQ(kReceiverLocalSsrc, ssrc); - observation_complete_->Set(); + EXPECT_EQ(kReceiverLocalVideoSsrc, ssrc); + observation_complete_.Set(); return SEND_PACKET; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while waiting for a receiver RTCP packet to be sent."; } } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { @@ -373,7 +375,6 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { public: NackObserver() : EndToEndTest(kLongTimeoutMs), - rtp_parser_(RtpHeaderParser::Create()), sent_rtp_packets_(0), packets_left_to_drop_(0), nacks_left_(kNumberOfNacksToObserve) {} @@ -382,7 +383,7 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { Action OnSendRtp(const uint8_t* packet, size_t length) override { rtc::CritScope lock(&crit_); RTPHeader header; - EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header)); + EXPECT_TRUE(parser_->Parse(packet, length, &header)); // Never drop retransmitted packets. if (dropped_packets_.find(header.sequenceNumber) != @@ -390,7 +391,7 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { retransmitted_packets_.insert(header.sequenceNumber); if (nacks_left_ <= 0 && retransmitted_packets_.size() == dropped_packets_.size()) { - observation_complete_->Set(); + observation_complete_.Set(); } return SEND_PACKET; } @@ -431,21 +432,21 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { return SEND_PACKET; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out waiting for packets to be NACKed, retransmitted and " "rendered."; } rtc::CriticalSection crit_; - rtc::scoped_ptr<RtpHeaderParser> rtp_parser_; std::set<uint16_t> dropped_packets_; std::set<uint16_t> retransmitted_packets_; uint64_t sent_rtp_packets_; @@ -453,7 +454,7 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { int nacks_left_ GUARDED_BY(&crit_); } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, CanReceiveFec) { @@ -472,10 +473,10 @@ TEST_F(EndToEndTest, CanReceiveFec) { if (header.payloadType == kRedPayloadType) { encapsulated_payload_type = static_cast<int>(packet[header.headerLength]); - if (encapsulated_payload_type != kFakeSendPayloadType) + if (encapsulated_payload_type != kFakeVideoSendPayloadType) EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); } else { - EXPECT_EQ(kFakeSendPayloadType, header.payloadType); + EXPECT_EQ(kFakeVideoSendPayloadType, header.payloadType); } if (protected_sequence_numbers_.count(header.sequenceNumber) != 0) { @@ -499,7 +500,7 @@ TEST_F(EndToEndTest, CanReceiveFec) { return DROP_PACKET; break; case kDropNextMediaPacket: - if (encapsulated_payload_type == kFakeSendPayloadType) { + if (encapsulated_payload_type == kFakeVideoSendPayloadType) { protected_sequence_numbers_.insert(header.sequenceNumber); protected_timestamps_.insert(header.timestamp); state_ = kDropEveryOtherPacketUntilFec; @@ -517,7 +518,7 @@ TEST_F(EndToEndTest, CanReceiveFec) { // Rendering frame with timestamp of packet that was dropped -> FEC // protection worked. if (protected_timestamps_.count(video_frame.timestamp()) != 0) - observation_complete_->Set(); + observation_complete_.Set(); } bool IsTextureSupported() const override { return false; } @@ -528,9 +529,10 @@ TEST_F(EndToEndTest, CanReceiveFec) { kDropNextMediaPacket, } state_; - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { // TODO(pbos): Run this test with combined NACK/FEC enabled as well. // int rtp_history_ms = 1000; // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms; @@ -544,7 +546,7 @@ TEST_F(EndToEndTest, CanReceiveFec) { } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out waiting for dropped frames frames to be rendered."; } @@ -553,14 +555,14 @@ TEST_F(EndToEndTest, CanReceiveFec) { std::set<uint32_t> protected_timestamps_ GUARDED_BY(crit_); } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } // Flacky on all platforms. See webrtc:4328. TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { class FecNackObserver : public test::EndToEndTest { public: - explicit FecNackObserver() + FecNackObserver() : EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket), fec_sequence_number_(0), @@ -569,6 +571,7 @@ TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { private: Action OnSendRtp(const uint8_t* packet, size_t length) override { + rtc::CritScope lock_(&crit_); RTPHeader header; EXPECT_TRUE(parser_->Parse(packet, length, &header)); @@ -576,10 +579,10 @@ TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { if (header.payloadType == kRedPayloadType) { encapsulated_payload_type = static_cast<int>(packet[header.headerLength]); - if (encapsulated_payload_type != kFakeSendPayloadType) + if (encapsulated_payload_type != kFakeVideoSendPayloadType) EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); } else { - EXPECT_EQ(kFakeSendPayloadType, header.payloadType); + EXPECT_EQ(kFakeVideoSendPayloadType, header.payloadType); } if (has_last_sequence_number_ && @@ -619,6 +622,7 @@ TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { } Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { + rtc::CritScope lock_(&crit_); if (state_ == kVerifyFecPacketNotInNackList) { test::RtcpPacketParser rtcp_parser; rtcp_parser.Parse(packet, length); @@ -627,12 +631,22 @@ TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { IsNewerSequenceNumber(nacks.back(), fec_sequence_number_)) { EXPECT_TRUE(std::find( nacks.begin(), nacks.end(), fec_sequence_number_) == nacks.end()); - observation_complete_->Set(); + observation_complete_.Set(); } } return SEND_PACKET; } + test::PacketTransport* CreateSendTransport(Call* sender_call) override { + // At low RTT (< kLowRttNackMs) -> NACK only, no FEC. + // Configure some network delay. + const int kNetworkDelayMs = 50; + FakeNetworkPipe::Config config; + config.queue_delay_ms = kNetworkDelayMs; + return new test::PacketTransport(sender_call, this, + test::PacketTransport::kSender, config); + } + // TODO(holmer): Investigate why we don't send FEC packets when the bitrate // is 10 kbps. Call::Config GetSenderCallConfig() override { @@ -642,9 +656,10 @@ TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { return config; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { // Configure hybrid NACK/FEC. send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; send_config->rtp.fec.red_payload_type = kRedPayloadType; @@ -655,7 +670,7 @@ TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while waiting for FEC packets to be received."; } @@ -666,17 +681,13 @@ TEST_F(EndToEndTest, DISABLED_ReceivedFecPacketsNotNacked) { kVerifyFecPacketNotInNackList, } state_; - uint16_t fec_sequence_number_; + rtc::CriticalSection crit_; + uint16_t fec_sequence_number_ GUARDED_BY(&crit_); bool has_last_sequence_number_; uint16_t last_sequence_number_; } test; - // At low RTT (< kLowRttNackMs) -> NACK only, no FEC. - // Configure some network delay. - const int kNetworkDelayMs = 50; - FakeNetworkPipe::Config config; - config.queue_delay_ms = kNetworkDelayMs; - RunBaseTest(&test, config); + RunBaseTest(&test); } // This test drops second RTP packet with a marker bit set, makes sure it's @@ -691,7 +702,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool use_rtx, bool use_red) { explicit RetransmissionObserver(bool use_rtx, bool use_red) : EndToEndTest(kDefaultTimeoutMs), payload_type_(GetPayloadType(false, use_red)), - retransmission_ssrc_(use_rtx ? kSendRtxSsrcs[0] : kSendSsrcs[0]), + retransmission_ssrc_(use_rtx ? kSendRtxSsrcs[0] : kVideoSendSsrcs[0]), retransmission_payload_type_(GetPayloadType(use_rtx, use_red)), marker_bits_observed_(0), num_packets_observed_(0), @@ -719,7 +730,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool use_rtx, bool use_red) { return SEND_PACKET; } - EXPECT_EQ(kSendSsrcs[0], header.ssrc); + EXPECT_EQ(kVideoSendSsrcs[0], header.ssrc); EXPECT_EQ(payload_type_, header.payloadType); // Found the final packet of the frame to inflict loss to, drop this and @@ -736,13 +747,14 @@ void EndToEndTest::DecodesRetransmittedFrame(bool use_rtx, bool use_red) { rtc::CritScope lock(&crit_); if (frame->timestamp() == retransmitted_timestamp_) { EXPECT_TRUE(frame_retransmitted_); - observation_complete_->Set(); + observation_complete_.Set(); } } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; (*receive_configs)[0].pre_render_callback = this; (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; @@ -757,21 +769,21 @@ void EndToEndTest::DecodesRetransmittedFrame(bool use_rtx, bool use_red) { if (retransmission_ssrc_ == kSendRtxSsrcs[0]) { send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); send_config->rtp.rtx.payload_type = kSendRtxPayloadType; - (*receive_configs)[0].rtp.rtx[kFakeSendPayloadType].ssrc = + (*receive_configs)[0].rtp.rtx[kFakeVideoSendPayloadType].ssrc = kSendRtxSsrcs[0]; - (*receive_configs)[0].rtp.rtx[kFakeSendPayloadType].payload_type = + (*receive_configs)[0].rtp.rtx[kFakeVideoSendPayloadType].payload_type = kSendRtxPayloadType; } } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while waiting for retransmission to render."; } int GetPayloadType(bool use_rtx, bool use_red) { return use_rtx ? kSendRtxPayloadType - : (use_red ? kRedPayloadType : kFakeSendPayloadType); + : (use_red ? kRedPayloadType : kFakeVideoSendPayloadType); } rtc::CriticalSection crit_; @@ -784,7 +796,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool use_rtx, bool use_red) { bool frame_retransmitted_; } test(use_rtx, use_red); - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, DecodesRetransmittedFrame) { @@ -809,30 +821,30 @@ TEST_F(EndToEndTest, UsesFrameCallbacks) { class Renderer : public VideoRenderer { public: - Renderer() : event_(EventWrapper::Create()) {} + Renderer() : event_(false, false) {} void RenderFrame(const VideoFrame& video_frame, int /*time_to_render_ms*/) override { EXPECT_EQ(0, *video_frame.buffer(kYPlane)) << "Rendered frame should have zero luma which is applied by the " "pre-render callback."; - event_->Set(); + event_.Set(); } bool IsTextureSupported() const override { return false; } - EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } - rtc::scoped_ptr<EventWrapper> event_; + bool Wait() { return event_.Wait(kDefaultTimeoutMs); } + rtc::Event event_; } renderer; class TestFrameCallback : public I420FrameCallback { public: TestFrameCallback(int expected_luma_byte, int next_luma_byte) - : event_(EventWrapper::Create()), + : event_(false, false), expected_luma_byte_(expected_luma_byte), next_luma_byte_(next_luma_byte) {} - EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } + bool Wait() { return event_.Wait(kDefaultTimeoutMs); } private: virtual void FrameCallback(VideoFrame* frame) { @@ -850,10 +862,10 @@ TEST_F(EndToEndTest, UsesFrameCallbacks) { next_luma_byte_, frame->allocated_size(kYPlane)); - event_->Set(); + event_.Set(); } - rtc::scoped_ptr<EventWrapper> event_; + rtc::Event event_; int expected_luma_byte_; int next_luma_byte_; }; @@ -868,34 +880,35 @@ TEST_F(EndToEndTest, UsesFrameCallbacks) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateSendConfig(1, &sender_transport); + CreateSendConfig(1, 0, &sender_transport); rtc::scoped_ptr<VideoEncoder> encoder( VideoEncoder::Create(VideoEncoder::kVp8)); - send_config_.encoder_settings.encoder = encoder.get(); - send_config_.encoder_settings.payload_name = "VP8"; - ASSERT_EQ(1u, encoder_config_.streams.size()) << "Test setup error."; - encoder_config_.streams[0].width = kWidth; - encoder_config_.streams[0].height = kHeight; - send_config_.pre_encode_callback = &pre_encode_callback; + video_send_config_.encoder_settings.encoder = encoder.get(); + video_send_config_.encoder_settings.payload_name = "VP8"; + ASSERT_EQ(1u, video_encoder_config_.streams.size()) << "Test setup error."; + video_encoder_config_.streams[0].width = kWidth; + video_encoder_config_.streams[0].height = kHeight; + video_send_config_.pre_encode_callback = &pre_encode_callback; CreateMatchingReceiveConfigs(&receiver_transport); - receive_configs_[0].pre_render_callback = &pre_render_callback; - receive_configs_[0].renderer = &renderer; + video_receive_configs_[0].pre_render_callback = &pre_render_callback; + video_receive_configs_[0].renderer = &renderer; - CreateStreams(); + CreateVideoStreams(); Start(); // Create frames that are smaller than the send width/height, this is done to // check that the callbacks are done after processing video. rtc::scoped_ptr<test::FrameGenerator> frame_generator( test::FrameGenerator::CreateChromaGenerator(kWidth / 2, kHeight / 2)); - send_stream_->Input()->IncomingCapturedFrame(*frame_generator->NextFrame()); + video_send_stream_->Input()->IncomingCapturedFrame( + *frame_generator->NextFrame()); - EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait()) + EXPECT_TRUE(pre_encode_callback.Wait()) << "Timed out while waiting for pre-encode callback."; - EXPECT_EQ(kEventSignaled, pre_render_callback.Wait()) + EXPECT_TRUE(pre_render_callback.Wait()) << "Timed out while waiting for pre-render callback."; - EXPECT_EQ(kEventSignaled, renderer.Wait()) + EXPECT_TRUE(renderer.Wait()) << "Timed out while waiting for the frame to render."; Stop(); @@ -962,7 +975,7 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) { rtc::CritScope lock(&crit_); if (received_pli_ && video_frame.timestamp() > highest_dropped_timestamp_) { - observation_complete_->Set(); + observation_complete_.Set(); } if (!received_pli_) frames_to_drop_ = kPacketsToDrop; @@ -970,18 +983,19 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) { bool IsTextureSupported() const override { return false; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->rtp.nack.rtp_history_ms = rtp_history_ms_; (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms_; (*receive_configs)[0].renderer = this; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) << "Timed out waiting for PLI to be " - "received and a frame to be " - "rendered afterwards."; + EXPECT_TRUE(Wait()) << "Timed out waiting for PLI to be " + "received and a frame to be " + "rendered afterwards."; } rtc::CriticalSection crit_; @@ -992,15 +1006,14 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) { bool received_pli_ GUARDED_BY(&crit_); } test(rtp_history_ms); - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) { ReceivesPliAndRecovers(1000); } -// TODO(pbos): Enable this when 2250 is resolved. -TEST_F(EndToEndTest, DISABLED_ReceivesPliAndRecoversWithoutNack) { +TEST_F(EndToEndTest, ReceivesPliAndRecoversWithoutNack) { ReceivesPliAndRecovers(0); } @@ -1008,11 +1021,9 @@ TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { class PacketInputObserver : public PacketReceiver { public: explicit PacketInputObserver(PacketReceiver* receiver) - : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {} + : receiver_(receiver), delivered_packet_(false, false) {} - EventTypeWrapper Wait() { - return delivered_packet_->Wait(kDefaultTimeoutMs); - } + bool Wait() { return delivered_packet_.Wait(kDefaultTimeoutMs); } private: DeliveryStatus DeliverPacket(MediaType media_type, @@ -1026,13 +1037,13 @@ TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { DeliveryStatus delivery_status = receiver_->DeliverPacket(media_type, packet, length, packet_time); EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status); - delivered_packet_->Set(); + delivered_packet_.Set(); return delivery_status; } } PacketReceiver* receiver_; - rtc::scoped_ptr<EventWrapper> delivered_packet_; + rtc::Event delivered_packet_; }; CreateCalls(Call::Config(), Call::Config()); @@ -1043,18 +1054,18 @@ TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { send_transport.SetReceiver(&input_observer); receive_transport.SetReceiver(sender_call_->Receiver()); - CreateSendConfig(1, &send_transport); + CreateSendConfig(1, 0, &send_transport); CreateMatchingReceiveConfigs(&receive_transport); - CreateStreams(); + CreateVideoStreams(); CreateFrameGeneratorCapturer(); Start(); - receiver_call_->DestroyVideoReceiveStream(receive_streams_[0]); - receive_streams_.clear(); + receiver_call_->DestroyVideoReceiveStream(video_receive_streams_[0]); + video_receive_streams_.clear(); // Wait() waits for a received packet. - EXPECT_EQ(kEventSignaled, input_observer.Wait()); + EXPECT_TRUE(input_observer.Wait()); Stop(); @@ -1103,16 +1114,16 @@ void EndToEndTest::RespectsRtcpMode(RtcpMode rtcp_mode) { if (!has_report_block) { ADD_FAILURE() << "Received RTCP packet without receiver report for " "RtcpMode::kCompound."; - observation_complete_->Set(); + observation_complete_.Set(); } if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve) - observation_complete_->Set(); + observation_complete_.Set(); break; case RtcpMode::kReducedSize: if (!has_report_block) - observation_complete_->Set(); + observation_complete_.Set(); break; case RtcpMode::kOff: RTC_NOTREACHED(); @@ -1122,16 +1133,17 @@ void EndToEndTest::RespectsRtcpMode(RtcpMode rtcp_mode) { return SEND_PACKET; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; (*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << (rtcp_mode_ == RtcpMode::kCompound ? "Timed out before observing enough compound packets." : "Timed out before receiving a non-compound RTCP packet."); @@ -1142,7 +1154,7 @@ void EndToEndTest::RespectsRtcpMode(RtcpMode rtcp_mode) { int sent_rtcp_; } test(rtcp_mode); - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, UsesRtcpCompoundMode) { @@ -1219,7 +1231,7 @@ class MultiStreamTest { VideoReceiveStream::Config receive_config(receiver_transport.get()); receive_config.rtp.remote_ssrc = ssrc; - receive_config.rtp.local_ssrc = test::CallTest::kReceiverLocalSsrc; + receive_config.rtp.local_ssrc = test::CallTest::kReceiverLocalVideoSsrc; VideoReceiveStream::Decoder decoder = test::CreateMatchingDecoder(send_config.encoder_settings); allocated_decoders.push_back(decoder.decoder); @@ -1282,27 +1294,27 @@ TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) { : settings_(settings), ssrc_(ssrc), frame_generator_(frame_generator), - done_(EventWrapper::Create()) {} + done_(false, false) {} void RenderFrame(const VideoFrame& video_frame, int time_to_render_ms) override { EXPECT_EQ(settings_.width, video_frame.width()); EXPECT_EQ(settings_.height, video_frame.height()); (*frame_generator_)->Stop(); - done_->Set(); + done_.Set(); } uint32_t Ssrc() { return ssrc_; } bool IsTextureSupported() const override { return false; } - EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); } + bool Wait() { return done_.Wait(kDefaultTimeoutMs); } private: const MultiStreamTest::CodecSettings& settings_; const uint32_t ssrc_; test::FrameGeneratorCapturer** const frame_generator_; - rtc::scoped_ptr<EventWrapper> done_; + rtc::Event done_; }; class Tester : public MultiStreamTest { @@ -1313,8 +1325,8 @@ TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) { protected: void Wait() override { for (const auto& observer : observers_) { - EXPECT_EQ(EventTypeWrapper::kEventSignaled, observer->Wait()) - << "Time out waiting for from on ssrc " << observer->Ssrc(); + EXPECT_TRUE(observer->Wait()) << "Time out waiting for from on ssrc " + << observer->Ssrc(); } } @@ -1350,7 +1362,7 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) { const uint32_t& first_media_ssrc, const std::map<uint32_t, uint32_t>& ssrc_map) : DirectTransport(sender_call), - done_(EventWrapper::Create()), + done_(false, false), parser_(RtpHeaderParser::Create()), first_media_ssrc_(first_media_ssrc), rtx_to_media_ssrcs_(ssrc_map), @@ -1419,7 +1431,7 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) { } if (IsDone()) - done_->Set(); + done_.Set(); if (drop_packet) return true; @@ -1441,18 +1453,18 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) { return seqno_range == received_packed_ids_.size(); } - EventTypeWrapper Wait() { + bool Wait() { { // Can't be sure until this point that rtx_to_media_ssrcs_ etc have // been initialized and are OK to read. rtc::CritScope cs(&lock_); started_ = true; } - return done_->Wait(kDefaultTimeoutMs); + return done_.Wait(kDefaultTimeoutMs); } rtc::CriticalSection lock_; - rtc::scoped_ptr<EventWrapper> done_; + rtc::Event done_; rtc::scoped_ptr<RtpHeaderParser> parser_; SequenceNumberUnwrapper unwrapper_; std::set<int64_t> received_packed_ids_; @@ -1475,7 +1487,7 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) { protected: void Wait() override { RTC_DCHECK(observer_ != nullptr); - EXPECT_EQ(EventTypeWrapper::kEventSignaled, observer_->Wait()); + EXPECT_TRUE(observer_->Wait()); } void UpdateSendConfig( @@ -1530,77 +1542,122 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) { tester.RunTest(); } -TEST_F(EndToEndTest, ReceivesTransportFeedback) { - static const int kExtensionId = 5; +class TransportFeedbackTester : public test::EndToEndTest { + public: + explicit TransportFeedbackTester(bool feedback_enabled, + size_t num_video_streams, + size_t num_audio_streams) + : EndToEndTest(::webrtc::EndToEndTest::kDefaultTimeoutMs), + feedback_enabled_(feedback_enabled), + num_video_streams_(num_video_streams), + num_audio_streams_(num_audio_streams) { + // Only one stream of each supported for now. + EXPECT_LE(num_video_streams, 1u); + EXPECT_LE(num_audio_streams, 1u); + } - class TransportFeedbackObserver : public test::DirectTransport { - public: - TransportFeedbackObserver(Call* receiver_call, rtc::Event* done_event) - : DirectTransport(receiver_call), done_(done_event) {} - virtual ~TransportFeedbackObserver() {} + protected: + Action OnSendRtcp(const uint8_t* data, size_t length) override { + EXPECT_FALSE(HasTransportFeedback(data, length)); + return SEND_PACKET; + } - bool SendRtcp(const uint8_t* data, size_t length) override { - RTCPUtility::RTCPParserV2 parser(data, length, true); - EXPECT_TRUE(parser.IsValid()); + Action OnReceiveRtcp(const uint8_t* data, size_t length) override { + if (HasTransportFeedback(data, length)) + observation_complete_.Set(); + return SEND_PACKET; + } - RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { - if (packet_type == RTCPUtility::RTCPPacketTypes::kTransportFeedback) { - done_->Set(); - break; - } - packet_type = parser.Iterate(); - } + bool HasTransportFeedback(const uint8_t* data, size_t length) const { + RTCPUtility::RTCPParserV2 parser(data, length, true); + EXPECT_TRUE(parser.IsValid()); - return test::DirectTransport::SendRtcp(data, length); + RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kTransportFeedback) + return true; + packet_type = parser.Iterate(); } - rtc::Event* done_; - }; + return false; + } - class TransportFeedbackTester : public MultiStreamTest { - public: - TransportFeedbackTester() : done_(false, false) {} - virtual ~TransportFeedbackTester() {} + void PerformTest() override { + const int64_t kDisabledFeedbackTimeoutMs = 5000; + EXPECT_EQ(feedback_enabled_, + observation_complete_.Wait(feedback_enabled_ + ? test::CallTest::kDefaultTimeoutMs + : kDisabledFeedbackTimeoutMs)); + } - protected: - void Wait() override { - EXPECT_TRUE(done_.Wait(CallTest::kDefaultTimeoutMs)); - } + void OnCallsCreated(Call* sender_call, Call* receiver_call) override { + receiver_call_ = receiver_call; + } - void UpdateSendConfig( - size_t stream_index, - VideoSendStream::Config* send_config, - VideoEncoderConfig* encoder_config, - test::FrameGeneratorCapturer** frame_generator) override { - send_config->rtp.extensions.push_back( - RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); - } + size_t GetNumVideoStreams() const override { return num_video_streams_; } + size_t GetNumAudioStreams() const override { return num_audio_streams_; } - void UpdateReceiveConfig( - size_t stream_index, - VideoReceiveStream::Config* receive_config) override { - receive_config->rtp.extensions.push_back( - RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); - } + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { + send_config->rtp.extensions.clear(); + send_config->rtp.extensions.push_back( + RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); + (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions; + (*receive_configs)[0].rtp.transport_cc = feedback_enabled_; + } - test::DirectTransport* CreateReceiveTransport( - Call* receiver_call) override { - return new TransportFeedbackObserver(receiver_call, &done_); - } + void ModifyAudioConfigs( + AudioSendStream::Config* send_config, + std::vector<AudioReceiveStream::Config>* receive_configs) override { + send_config->rtp.extensions.clear(); + send_config->rtp.extensions.push_back( + RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); + (*receive_configs)[0].rtp.extensions.clear(); + (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions; + (*receive_configs)[0].rtp.transport_cc = feedback_enabled_; + (*receive_configs)[0].combined_audio_video_bwe = true; + } - private: - rtc::Event done_; - } tester; - tester.RunTest(); + private: + static const int kExtensionId = 5; + const bool feedback_enabled_; + const size_t num_video_streams_; + const size_t num_audio_streams_; + Call* receiver_call_; +}; + +TEST_F(EndToEndTest, VideoReceivesTransportFeedback) { + TransportFeedbackTester test(true, 1, 0); + RunBaseTest(&test); +} + +TEST_F(EndToEndTest, VideoTransportFeedbackNotConfigured) { + TransportFeedbackTester test(false, 1, 0); + RunBaseTest(&test); +} + +TEST_F(EndToEndTest, AudioReceivesTransportFeedback) { + TransportFeedbackTester test(true, 0, 1); + RunBaseTest(&test); +} + +TEST_F(EndToEndTest, AudioTransportFeedbackNotConfigured) { + TransportFeedbackTester test(false, 0, 1); + RunBaseTest(&test); } + +TEST_F(EndToEndTest, AudioVideoReceivesTransportFeedback) { + TransportFeedbackTester test(true, 1, 1); + RunBaseTest(&test); +} + TEST_F(EndToEndTest, ObserversEncodedFrames) { class EncodedFrameTestObserver : public EncodedFrameObserver { public: EncodedFrameTestObserver() - : length_(0), - frame_type_(kEmptyFrame), - called_(EventWrapper::Create()) {} + : length_(0), frame_type_(kEmptyFrame), called_(false, false) {} virtual ~EncodedFrameTestObserver() {} virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) { @@ -1608,10 +1665,10 @@ TEST_F(EndToEndTest, ObserversEncodedFrames) { length_ = encoded_frame.length_; buffer_.reset(new uint8_t[length_]); memcpy(buffer_.get(), encoded_frame.data_, length_); - called_->Set(); + called_.Set(); } - EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); } + bool Wait() { return called_.Wait(kDefaultTimeoutMs); } void ExpectEqualFrames(const EncodedFrameTestObserver& observer) { ASSERT_EQ(length_, observer.length_) @@ -1626,7 +1683,7 @@ TEST_F(EndToEndTest, ObserversEncodedFrames) { rtc::scoped_ptr<uint8_t[]> buffer_; size_t length_; FrameType frame_type_; - rtc::scoped_ptr<EventWrapper> called_; + rtc::Event called_; }; EncodedFrameTestObserver post_encode_observer; @@ -1639,23 +1696,25 @@ TEST_F(EndToEndTest, ObserversEncodedFrames) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateSendConfig(1, &sender_transport); + CreateSendConfig(1, 0, &sender_transport); CreateMatchingReceiveConfigs(&receiver_transport); - send_config_.post_encode_callback = &post_encode_observer; - receive_configs_[0].pre_decode_callback = &pre_decode_observer; + video_send_config_.post_encode_callback = &post_encode_observer; + video_receive_configs_[0].pre_decode_callback = &pre_decode_observer; - CreateStreams(); + CreateVideoStreams(); Start(); rtc::scoped_ptr<test::FrameGenerator> frame_generator( test::FrameGenerator::CreateChromaGenerator( - encoder_config_.streams[0].width, encoder_config_.streams[0].height)); - send_stream_->Input()->IncomingCapturedFrame(*frame_generator->NextFrame()); + video_encoder_config_.streams[0].width, + video_encoder_config_.streams[0].height)); + video_send_stream_->Input()->IncomingCapturedFrame( + *frame_generator->NextFrame()); - EXPECT_EQ(kEventSignaled, post_encode_observer.Wait()) + EXPECT_TRUE(post_encode_observer.Wait()) << "Timed out while waiting for send-side encoded-frame callback."; - EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait()) + EXPECT_TRUE(pre_decode_observer.Wait()) << "Timed out while waiting for pre-decode encoded-frame callback."; post_encode_observer.ExpectEqualFrames(pre_decode_observer); @@ -1683,29 +1742,29 @@ TEST_F(EndToEndTest, ReceiveStreamSendsRemb) { while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbRemb) { const RTCPUtility::RTCPPacket& packet = parser.Packet(); - EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc); + EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalVideoSsrc); received_psfb = true; } else if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbRembItem) { const RTCPUtility::RTCPPacket& packet = parser.Packet(); EXPECT_GT(packet.REMBItem.BitRate, 0u); EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u); - EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrcs[0]); + EXPECT_EQ(packet.REMBItem.SSRCs[0], kVideoSendSsrcs[0]); received_remb = true; } packet_type = parser.Iterate(); } if (received_psfb && received_remb) - observation_complete_->Set(); + observation_complete_.Set(); return SEND_PACKET; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for a " - "receiver RTCP REMB packet to be " - "sent."; + EXPECT_TRUE(Wait()) << "Timed out while waiting for a " + "receiver RTCP REMB packet to be " + "sent."; } } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, VerifyBandwidthStats) { @@ -1724,7 +1783,7 @@ TEST_F(EndToEndTest, VerifyBandwidthStats) { has_seen_pacer_delay_ = sender_stats.pacer_delay_ms > 0; if (sender_stats.send_bandwidth_bps > 0 && receiver_stats.recv_bandwidth_bps > 0 && has_seen_pacer_delay_) { - observation_complete_->Set(); + observation_complete_.Set(); } return SEND_PACKET; } @@ -1735,8 +1794,8 @@ TEST_F(EndToEndTest, VerifyBandwidthStats) { } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for " - "non-zero bandwidth stats."; + EXPECT_TRUE(Wait()) << "Timed out while waiting for " + "non-zero bandwidth stats."; } private: @@ -1745,7 +1804,7 @@ TEST_F(EndToEndTest, VerifyBandwidthStats) { bool has_seen_pacer_delay_; } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, VerifyNackStats) { @@ -1762,6 +1821,7 @@ TEST_F(EndToEndTest, VerifyNackStats) { private: Action OnSendRtp(const uint8_t* packet, size_t length) override { + rtc::CritScope lock(&crit_); if (++sent_rtp_packets_ == kPacketNumberToDrop) { rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); RTPHeader header; @@ -1774,6 +1834,7 @@ TEST_F(EndToEndTest, VerifyNackStats) { } Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { + rtc::CritScope lock(&crit_); test::RtcpPacketParser rtcp_parser; rtcp_parser.Parse(packet, length); std::vector<uint16_t> nacks = rtcp_parser.nack_item()->last_nack_list(); @@ -1784,7 +1845,7 @@ TEST_F(EndToEndTest, VerifyNackStats) { return SEND_PACKET; } - void VerifyStats() { + void VerifyStats() EXCLUSIVE_LOCKS_REQUIRED(&crit_) { if (!dropped_rtp_packet_requested_) return; int send_stream_nack_packets = 0; @@ -1804,7 +1865,7 @@ TEST_F(EndToEndTest, VerifyNackStats) { if (send_stream_nack_packets >= 1 && receive_stream_nack_packets >= 1) { // NACK packet sent on receive stream and received on sent stream. if (MinMetricRunTimePassed()) - observation_complete_->Set(); + observation_complete_.Set(); } } @@ -1818,14 +1879,15 @@ TEST_F(EndToEndTest, VerifyNackStats) { return elapsed_sec > metrics::kMinRunTimeInSeconds; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; } - void OnStreamsCreated( + void OnVideoStreamsCreated( VideoSendStream* send_stream, const std::vector<VideoReceiveStream*>& receive_streams) override { send_stream_ = send_stream; @@ -1833,20 +1895,20 @@ TEST_F(EndToEndTest, VerifyNackStats) { } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) - << "Timed out waiting for packet to be NACKed."; + EXPECT_TRUE(Wait()) << "Timed out waiting for packet to be NACKed."; } + rtc::CriticalSection crit_; uint64_t sent_rtp_packets_; - uint16_t dropped_rtp_packet_; - bool dropped_rtp_packet_requested_; + uint16_t dropped_rtp_packet_ GUARDED_BY(&crit_); + bool dropped_rtp_packet_requested_ GUARDED_BY(&crit_); std::vector<VideoReceiveStream*> receive_streams_; VideoSendStream* send_stream_; int64_t start_runtime_ms_; } test; test::ClearHistograms(); - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.UniqueNackRequestsSentInPercent")); @@ -1858,13 +1920,16 @@ TEST_F(EndToEndTest, VerifyNackStats) { "WebRTC.Video.NackPacketsReceivedPerMinute"), 0); } -void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { +void EndToEndTest::VerifyHistogramStats(bool use_rtx, + bool use_red, + bool screenshare) { class StatsObserver : public test::EndToEndTest { public: - StatsObserver(bool use_rtx, bool use_red) + StatsObserver(bool use_rtx, bool use_red, bool screenshare) : EndToEndTest(kLongTimeoutMs), use_rtx_(use_rtx), use_red_(use_red), + screenshare_(screenshare), sender_call_(nullptr), receiver_call_(nullptr), start_runtime_ms_(-1) {} @@ -1872,7 +1937,7 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { private: Action OnSendRtp(const uint8_t* packet, size_t length) override { if (MinMetricRunTimePassed()) - observation_complete_->Set(); + observation_complete_.Set(); // GetStats calls GetSendChannelRtcpStatistics // (via VideoSendStream::GetRtt) which updates ReportBlockStats used by @@ -1893,9 +1958,10 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { return elapsed_sec > metrics::kMinRunTimeInSeconds * 2; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { // NACK send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; @@ -1910,11 +1976,14 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { if (use_rtx_) { send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); send_config->rtp.rtx.payload_type = kSendRtxPayloadType; - (*receive_configs)[0].rtp.rtx[kFakeSendPayloadType].ssrc = + (*receive_configs)[0].rtp.rtx[kFakeVideoSendPayloadType].ssrc = kSendRtxSsrcs[0]; - (*receive_configs)[0].rtp.rtx[kFakeSendPayloadType].payload_type = + (*receive_configs)[0].rtp.rtx[kFakeVideoSendPayloadType].payload_type = kSendRtxPayloadType; } + encoder_config->content_type = + screenshare_ ? VideoEncoderConfig::ContentType::kScreen + : VideoEncoderConfig::ContentType::kRealtimeVideo; } void OnCallsCreated(Call* sender_call, Call* receiver_call) override { @@ -1923,21 +1992,37 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) - << "Timed out waiting for packet to be NACKed."; + EXPECT_TRUE(Wait()) << "Timed out waiting for packet to be NACKed."; } - bool use_rtx_; - bool use_red_; + const bool use_rtx_; + const bool use_red_; + const bool screenshare_; Call* sender_call_; Call* receiver_call_; int64_t start_runtime_ms_; - } test(use_rtx, use_red); + } test(use_rtx, use_red, screenshare); test::ClearHistograms(); - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); + + // Delete the call for Call stats to be reported. + sender_call_.reset(); + receiver_call_.reset(); + + std::string video_prefix = + screenshare ? "WebRTC.Video.Screenshare." : "WebRTC.Video."; // Verify that stats have been updated once. + EXPECT_EQ( + 1, test::NumHistogramSamples("WebRTC.Call.VideoBitrateReceivedInKbps")); + EXPECT_EQ(1, + test::NumHistogramSamples("WebRTC.Call.RtcpBitrateReceivedInBps")); + EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Call.BitrateReceivedInKbps")); + EXPECT_EQ( + 1, test::NumHistogramSamples("WebRTC.Call.EstimatedSendBitrateInKbps")); + EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Call.PacerBitrateInKbps")); + EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.NackPacketsSentPerMinute")); EXPECT_EQ(1, test::NumHistogramSamples( @@ -1951,8 +2036,8 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.PliPacketsReceivedPerMinute")); - EXPECT_EQ(1, test::NumHistogramSamples( - "WebRTC.Video.KeyFramesSentInPermille")); + EXPECT_EQ( + 1, test::NumHistogramSamples(video_prefix + "KeyFramesSentInPermille")); EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.KeyFramesReceivedInPermille")); @@ -1961,34 +2046,39 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.ReceivedPacketsLostInPercent")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputWidthInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputHeightInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentWidthInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentHeightInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "InputWidthInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "InputHeightInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SentWidthInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SentHeightInPixels")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.ReceivedWidthInPixels")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.ReceivedHeightInPixels")); - EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].width), - test::LastHistogramSample("WebRTC.Video.InputWidthInPixels")); - EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].height), - test::LastHistogramSample("WebRTC.Video.InputHeightInPixels")); - EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].width), - test::LastHistogramSample("WebRTC.Video.SentWidthInPixels")); - EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].height), - test::LastHistogramSample("WebRTC.Video.SentHeightInPixels")); - EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].width), + EXPECT_EQ(static_cast<int>(video_encoder_config_.streams[0].width), + test::LastHistogramSample(video_prefix + "InputWidthInPixels")); + EXPECT_EQ(static_cast<int>(video_encoder_config_.streams[0].height), + test::LastHistogramSample(video_prefix + "InputHeightInPixels")); + EXPECT_EQ(static_cast<int>(video_encoder_config_.streams[0].width), + test::LastHistogramSample(video_prefix + "SentWidthInPixels")); + EXPECT_EQ(static_cast<int>(video_encoder_config_.streams[0].height), + test::LastHistogramSample(video_prefix + "SentHeightInPixels")); + EXPECT_EQ(static_cast<int>(video_encoder_config_.streams[0].width), test::LastHistogramSample("WebRTC.Video.ReceivedWidthInPixels")); - EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].height), + EXPECT_EQ(static_cast<int>(video_encoder_config_.streams[0].height), test::LastHistogramSample("WebRTC.Video.ReceivedHeightInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputFramesPerSecond")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentFramesPerSecond")); + EXPECT_EQ(1, + test::NumHistogramSamples(video_prefix + "InputFramesPerSecond")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SentFramesPerSecond")); EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.DecodedFramesPerSecond")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.RenderFramesPerSecond")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.EncodeTimeInMs")); + EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.OnewayDelayInMs")); + EXPECT_EQ( + 1, test::NumHistogramSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); + + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "EncodeTimeInMs")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.DecodeTimeInMs")); EXPECT_EQ(1, test::NumHistogramSamples( @@ -2008,6 +2098,10 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.RetransmittedBitrateReceivedInKbps")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SendSideDelayInMs")); + EXPECT_EQ(1, + test::NumHistogramSamples(video_prefix + "SendSideDelayMaxInMs")); + int num_rtx_samples = use_rtx ? 1 : 0; EXPECT_EQ(num_rtx_samples, test::NumHistogramSamples( "WebRTC.Video.RtxBitrateSentInKbps")); @@ -2026,13 +2120,22 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { TEST_F(EndToEndTest, VerifyHistogramStatsWithRtx) { const bool kEnabledRtx = true; const bool kEnabledRed = false; - VerifyHistogramStats(kEnabledRtx, kEnabledRed); + const bool kScreenshare = false; + VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); } TEST_F(EndToEndTest, VerifyHistogramStatsWithRed) { const bool kEnabledRtx = false; const bool kEnabledRed = true; - VerifyHistogramStats(kEnabledRtx, kEnabledRed); + const bool kScreenshare = false; + VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); +} + +TEST_F(EndToEndTest, VerifyHistogramStatsWithScreenshare) { + const bool kEnabledRtx = false; + const bool kEnabledRed = false; + const bool kScreenshare = true; + VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); } void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { @@ -2050,6 +2153,7 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { private: // Receive stream should send RR packets (and RRTR packets if enabled). Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { + rtc::CritScope lock(&crit_); RTCPUtility::RTCPParserV2 parser(packet, length, true); EXPECT_TRUE(parser.IsValid()); @@ -2070,6 +2174,7 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { } // Send stream should send SR packets (and DLRR packets if enabled). virtual Action OnSendRtcp(const uint8_t* packet, size_t length) { + rtc::CritScope lock(&crit_); RTCPUtility::RTCPParserV2 parser(packet, length, true); EXPECT_TRUE(parser.IsValid()); @@ -2094,32 +2199,34 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { EXPECT_EQ(0, sent_rtcp_rrtr_); EXPECT_EQ(0, sent_rtcp_dlrr_); } - observation_complete_->Set(); + observation_complete_.Set(); } return SEND_PACKET; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { (*receive_configs)[0].rtp.rtcp_mode = RtcpMode::kReducedSize; (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr_; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP SR/RR packets to be sent."; } + rtc::CriticalSection crit_; bool enable_rrtr_; int sent_rtcp_sr_; - int sent_rtcp_rr_; - int sent_rtcp_rrtr_; + int sent_rtcp_rr_ GUARDED_BY(&crit_); + int sent_rtcp_rrtr_ GUARDED_BY(&crit_); int sent_rtcp_dlrr_; } test(enable_rrtr); - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs, @@ -2148,28 +2255,29 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs, << "Received unknown SSRC: " << header.ssrc; if (!valid_ssrcs_[header.ssrc]) - observation_complete_->Set(); + observation_complete_.Set(); if (!is_observed_[header.ssrc]) { is_observed_[header.ssrc] = true; --ssrcs_to_observe_; if (expect_single_ssrc_) { expect_single_ssrc_ = false; - observation_complete_->Set(); + observation_complete_.Set(); } } if (ssrcs_to_observe_ == 0) - observation_complete_->Set(); + observation_complete_.Set(); return SEND_PACKET; } - size_t GetNumStreams() const override { return num_ssrcs_; } + size_t GetNumVideoStreams() const override { return num_ssrcs_; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { if (num_ssrcs_ > 1) { // Set low simulcast bitrates to not have to wait for bandwidth ramp-up. for (size_t i = 0; i < encoder_config->streams.size(); ++i) { @@ -2179,27 +2287,27 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs, } } - encoder_config_all_streams_ = *encoder_config; + video_encoder_config_all_streams_ = *encoder_config; if (send_single_ssrc_first_) encoder_config->streams.resize(1); } - void OnStreamsCreated( + void OnVideoStreamsCreated( VideoSendStream* send_stream, const std::vector<VideoReceiveStream*>& receive_streams) override { send_stream_ = send_stream; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) - << "Timed out while waiting for " - << (send_single_ssrc_first_ ? "first SSRC." : "SSRCs."); + EXPECT_TRUE(Wait()) << "Timed out while waiting for " + << (send_single_ssrc_first_ ? "first SSRC." + : "SSRCs."); if (send_single_ssrc_first_) { // Set full simulcast and continue with the rest of the SSRCs. - send_stream_->ReconfigureVideoEncoder(encoder_config_all_streams_); - EXPECT_EQ(kEventSignaled, Wait()) - << "Timed out while waiting on additional SSRCs."; + send_stream_->ReconfigureVideoEncoder( + video_encoder_config_all_streams_); + EXPECT_TRUE(Wait()) << "Timed out while waiting on additional SSRCs."; } } @@ -2214,10 +2322,10 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs, bool expect_single_ssrc_; VideoSendStream* send_stream_; - VideoEncoderConfig encoder_config_all_streams_; - } test(kSendSsrcs, num_ssrcs, send_single_ssrc_first); + VideoEncoderConfig video_encoder_config_all_streams_; + } test(kVideoSendSsrcs, num_ssrcs, send_single_ssrc_first); - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, ReportsSetEncoderRates) { @@ -2230,15 +2338,16 @@ TEST_F(EndToEndTest, ReportsSetEncoderRates) { send_stream_(nullptr), bitrate_kbps_(0) {} - void OnStreamsCreated( + void OnVideoStreamsCreated( VideoSendStream* send_stream, const std::vector<VideoReceiveStream*>& receive_streams) override { send_stream_ = send_stream; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->encoder_settings.encoder = this; } @@ -2248,15 +2357,15 @@ TEST_F(EndToEndTest, ReportsSetEncoderRates) { return 0; rtc::CritScope lock(&crit_); bitrate_kbps_ = new_target_bitrate; - observation_complete_->Set(); + observation_complete_.Set(); return 0; } void PerformTest() override { - ASSERT_EQ(kEventSignaled, Wait()) + ASSERT_TRUE(Wait()) << "Timed out while waiting for encoder SetRates() call."; // Wait for GetStats to report a corresponding bitrate. - for (unsigned int i = 0; i < kDefaultTimeoutMs; ++i) { + for (int i = 0; i < kDefaultTimeoutMs; ++i) { VideoSendStream::Stats stats = send_stream_->GetStats(); { rtc::CritScope lock(&crit_); @@ -2277,7 +2386,7 @@ TEST_F(EndToEndTest, ReportsSetEncoderRates) { uint32_t bitrate_kbps_ GUARDED_BY(crit_); } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, GetStats) { @@ -2289,26 +2398,26 @@ TEST_F(EndToEndTest, GetStats) { : EndToEndTest(kLongTimeoutMs), send_stream_(nullptr), expected_send_ssrcs_(), - check_stats_event_(EventWrapper::Create()) {} + check_stats_event_(false, false) {} private: Action OnSendRtp(const uint8_t* packet, size_t length) override { - check_stats_event_->Set(); + check_stats_event_.Set(); return SEND_PACKET; } Action OnSendRtcp(const uint8_t* packet, size_t length) override { - check_stats_event_->Set(); + check_stats_event_.Set(); return SEND_PACKET; } Action OnReceiveRtp(const uint8_t* packet, size_t length) override { - check_stats_event_->Set(); + check_stats_event_.Set(); return SEND_PACKET; } Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { - check_stats_event_->Set(); + check_stats_event_.Set(); return SEND_PACKET; } @@ -2330,6 +2439,9 @@ TEST_F(EndToEndTest, GetStats) { receive_stats_filled_["IncomingRate"] |= stats.network_frame_rate != 0 || stats.total_bitrate_bps != 0; + send_stats_filled_["DecoderImplementationName"] |= + stats.decoder_implementation_name == + test::FakeDecoder::kImplementationName; receive_stats_filled_["RenderDelayAsHighAsExpected"] |= stats.render_delay_ms >= kExpectedRenderDelayMs; @@ -2367,9 +2479,9 @@ TEST_F(EndToEndTest, GetStats) { stats.rtcp_packet_type_counts.unique_nack_requests != 0; assert(stats.current_payload_type == -1 || - stats.current_payload_type == kFakeSendPayloadType); + stats.current_payload_type == kFakeVideoSendPayloadType); receive_stats_filled_["IncomingPayloadType"] |= - stats.current_payload_type == kFakeSendPayloadType; + stats.current_payload_type == kFakeVideoSendPayloadType; } return AllStatsFilled(receive_stats_filled_); @@ -2385,6 +2497,10 @@ TEST_F(EndToEndTest, GetStats) { send_stats_filled_["CpuOveruseMetrics"] |= stats.avg_encode_time_ms != 0 || stats.encode_usage_percent != 0; + send_stats_filled_["EncoderImplementationName"] |= + stats.encoder_implementation_name == + test::FakeEncoder::kImplementationName; + for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it = stats.substreams.begin(); it != stats.substreams.end(); ++it) { @@ -2450,15 +2566,23 @@ TEST_F(EndToEndTest, GetStats) { return true; } + test::PacketTransport* CreateSendTransport(Call* sender_call) override { + FakeNetworkPipe::Config network_config; + network_config.loss_percent = 5; + return new test::PacketTransport( + sender_call, this, test::PacketTransport::kSender, network_config); + } + Call::Config GetSenderCallConfig() override { Call::Config config = EndToEndTest::GetSenderCallConfig(); config.bitrate_config.start_bitrate_bps = kStartBitrateBps; return config; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->pre_encode_callback = this; // Used to inject delay. expected_cname_ = send_config->rtp.c_name = "SomeCName"; @@ -2471,9 +2595,9 @@ TEST_F(EndToEndTest, GetStats) { } } - size_t GetNumStreams() const override { return kNumSsrcs; } + size_t GetNumVideoStreams() const override { return kNumSsrcs; } - void OnStreamsCreated( + void OnVideoStreamsCreated( VideoSendStream* send_stream, const std::vector<VideoReceiveStream*>& receive_streams) override { send_stream_ = send_stream; @@ -2498,7 +2622,7 @@ TEST_F(EndToEndTest, GetStats) { int64_t time_until_timout_ = stop_time - now; if (time_until_timout_ > 0) - check_stats_event_->Wait(time_until_timout_); + check_stats_event_.Wait(time_until_timout_); now = clock->TimeInMilliseconds(); } @@ -2532,12 +2656,10 @@ TEST_F(EndToEndTest, GetStats) { std::set<uint32_t> expected_send_ssrcs_; std::string expected_cname_; - rtc::scoped_ptr<EventWrapper> check_stats_event_; + rtc::Event check_stats_event_; } test; - FakeNetworkPipe::Config network_config; - network_config.loss_percent = 5; - RunBaseTest(&test, network_config); + RunBaseTest(&test); } TEST_F(EndToEndTest, ReceiverReferenceTimeReportEnabled) { @@ -2558,7 +2680,7 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) { sent_rtp_(0) {} private: - void OnStreamsCreated( + void OnVideoStreamsCreated( VideoSendStream* send_stream, const std::vector<VideoReceiveStream*>& receive_streams) override { receive_stream_ = receive_streams[0]; @@ -2568,7 +2690,7 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) { if (sent_rtp_ >= kNumRtpPacketsToSend) { VideoReceiveStream::Stats stats = receive_stream_->GetStats(); if (kNumRtpPacketsToSend == stats.rtp_stats.transmitted.packets) { - observation_complete_->Set(); + observation_complete_.Set(); } return DROP_PACKET; } @@ -2577,7 +2699,7 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) { } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while verifying number of received RTP packets."; } @@ -2585,7 +2707,7 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) { uint32_t sent_rtp_; } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, SendsSetSsrc) { TestSendsSetSsrcs(1, false); } @@ -2626,17 +2748,18 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { if (!observed_redundant_retransmission_[header.ssrc]) { observed_redundant_retransmission_[header.ssrc] = true; if (--ssrcs_to_observe_ == 0) - observation_complete_->Set(); + observation_complete_.Set(); } return SEND_PACKET; } - size_t GetNumStreams() const override { return kNumSsrcs; } + size_t GetNumVideoStreams() const override { return kNumSsrcs; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { // Set low simulcast bitrates to not have to wait for bandwidth ramp-up. for (size_t i = 0; i < encoder_config->streams.size(); ++i) { encoder_config->streams[i].min_bitrate_bps = 10000; @@ -2655,7 +2778,7 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { } void PerformTest() override { - EXPECT_EQ(kEventSignaled, Wait()) + EXPECT_TRUE(Wait()) << "Timed out while waiting for redundant payloads on all SSRCs."; } @@ -2665,7 +2788,7 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { std::map<uint32_t, bool> registered_rtx_ssrc_; } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { @@ -2677,7 +2800,7 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { : test::RtpRtcpObserver(kDefaultTimeoutMs), ssrcs_to_observe_(kNumSsrcs) { for (size_t i = 0; i < kNumSsrcs; ++i) { - configured_ssrcs_[kSendSsrcs[i]] = true; + configured_ssrcs_[kVideoSendSsrcs[i]] = true; if (use_rtx) configured_ssrcs_[kSendRtxSsrcs[i]] = true; } @@ -2744,7 +2867,7 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { if (!ssrc_observed_[ssrc] && !only_padding) { ssrc_observed_[ssrc] = true; if (--ssrcs_to_observe_ == 0) - observation_complete_->Set(); + observation_complete_.Set(); } return SEND_PACKET; @@ -2770,77 +2893,75 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { send_transport.SetReceiver(receiver_call_->Receiver()); receive_transport.SetReceiver(sender_call_->Receiver()); - CreateSendConfig(kNumSsrcs, &send_transport); + CreateSendConfig(kNumSsrcs, 0, &send_transport); if (use_rtx) { for (size_t i = 0; i < kNumSsrcs; ++i) { - send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); + video_send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); } - send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; + video_send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; } // Lower bitrates so that all streams send initially. - for (size_t i = 0; i < encoder_config_.streams.size(); ++i) { - encoder_config_.streams[i].min_bitrate_bps = 10000; - encoder_config_.streams[i].target_bitrate_bps = 15000; - encoder_config_.streams[i].max_bitrate_bps = 20000; + for (size_t i = 0; i < video_encoder_config_.streams.size(); ++i) { + video_encoder_config_.streams[i].min_bitrate_bps = 10000; + video_encoder_config_.streams[i].target_bitrate_bps = 15000; + video_encoder_config_.streams[i].max_bitrate_bps = 20000; } // Use the same total bitrates when sending a single stream to avoid lowering // the bitrate estimate and requiring a subsequent rampup. - VideoEncoderConfig one_stream = encoder_config_; + VideoEncoderConfig one_stream = video_encoder_config_; one_stream.streams.resize(1); - for (size_t i = 1; i < encoder_config_.streams.size(); ++i) { + for (size_t i = 1; i < video_encoder_config_.streams.size(); ++i) { one_stream.streams.front().min_bitrate_bps += - encoder_config_.streams[i].min_bitrate_bps; + video_encoder_config_.streams[i].min_bitrate_bps; one_stream.streams.front().target_bitrate_bps += - encoder_config_.streams[i].target_bitrate_bps; + video_encoder_config_.streams[i].target_bitrate_bps; one_stream.streams.front().max_bitrate_bps += - encoder_config_.streams[i].max_bitrate_bps; + video_encoder_config_.streams[i].max_bitrate_bps; } CreateMatchingReceiveConfigs(&receive_transport); - CreateStreams(); + CreateVideoStreams(); CreateFrameGeneratorCapturer(); Start(); - EXPECT_EQ(kEventSignaled, observer.Wait()) + EXPECT_TRUE(observer.Wait()) << "Timed out waiting for all SSRCs to send packets."; // Test stream resetting more than once to make sure that the state doesn't // get set once (this could be due to using std::map::insert for instance). for (size_t i = 0; i < 3; ++i) { frame_generator_capturer_->Stop(); - sender_call_->DestroyVideoSendStream(send_stream_); + sender_call_->DestroyVideoSendStream(video_send_stream_); // Re-create VideoSendStream with only one stream. - send_stream_ = - sender_call_->CreateVideoSendStream(send_config_, one_stream); - send_stream_->Start(); + video_send_stream_ = + sender_call_->CreateVideoSendStream(video_send_config_, one_stream); + video_send_stream_->Start(); CreateFrameGeneratorCapturer(); frame_generator_capturer_->Start(); observer.ResetExpectedSsrcs(1); - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out waiting for single RTP packet."; + EXPECT_TRUE(observer.Wait()) << "Timed out waiting for single RTP packet."; // Reconfigure back to use all streams. - send_stream_->ReconfigureVideoEncoder(encoder_config_); + video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_); observer.ResetExpectedSsrcs(kNumSsrcs); - EXPECT_EQ(kEventSignaled, observer.Wait()) + EXPECT_TRUE(observer.Wait()) << "Timed out waiting for all SSRCs to send packets."; // Reconfigure down to one stream. - send_stream_->ReconfigureVideoEncoder(one_stream); + video_send_stream_->ReconfigureVideoEncoder(one_stream); observer.ResetExpectedSsrcs(1); - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out waiting for single RTP packet."; + EXPECT_TRUE(observer.Wait()) << "Timed out waiting for single RTP packet."; // Reconfigure back to use all streams. - send_stream_->ReconfigureVideoEncoder(encoder_config_); + video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_); observer.ResetExpectedSsrcs(kNumSsrcs); - EXPECT_EQ(kEventSignaled, observer.Wait()) + EXPECT_TRUE(observer.Wait()) << "Timed out waiting for all SSRCs to send packets."; } @@ -2874,8 +2995,8 @@ TEST_F(EndToEndTest, RespectsNetworkState) { NetworkStateTest() : EndToEndTest(kDefaultTimeoutMs), FakeEncoder(Clock::GetRealTimeClock()), - encoded_frames_(EventWrapper::Create()), - packet_event_(EventWrapper::Create()), + encoded_frames_(false, false), + packet_event_(false, false), sender_call_(nullptr), receiver_call_(nullptr), sender_state_(kNetworkUp), @@ -2887,14 +3008,14 @@ TEST_F(EndToEndTest, RespectsNetworkState) { Action OnSendRtp(const uint8_t* packet, size_t length) override { rtc::CritScope lock(&test_crit_); ++sender_rtp_; - packet_event_->Set(); + packet_event_.Set(); return SEND_PACKET; } Action OnSendRtcp(const uint8_t* packet, size_t length) override { rtc::CritScope lock(&test_crit_); ++sender_rtcp_; - packet_event_->Set(); + packet_event_.Set(); return SEND_PACKET; } @@ -2906,7 +3027,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) { Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { rtc::CritScope lock(&test_crit_); ++receiver_rtcp_; - packet_event_->Set(); + packet_event_.Set(); return SEND_PACKET; } @@ -2915,14 +3036,15 @@ TEST_F(EndToEndTest, RespectsNetworkState) { receiver_call_ = receiver_call; } - void ModifyConfigs(VideoSendStream::Config* send_config, - std::vector<VideoReceiveStream::Config>* receive_configs, - VideoEncoderConfig* encoder_config) override { + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { send_config->encoder_settings.encoder = this; } void PerformTest() override { - EXPECT_EQ(kEventSignaled, encoded_frames_->Wait(kDefaultTimeoutMs)) + EXPECT_TRUE(encoded_frames_.Wait(kDefaultTimeoutMs)) << "No frames received by the encoder."; // Wait for packets from both sender/receiver. WaitForPacketsOrSilence(false, false); @@ -2963,9 +3085,9 @@ TEST_F(EndToEndTest, RespectsNetworkState) { EXPECT_LE(down_frames_, 1) << "Encoding more than one frame while network is down."; if (down_frames_ > 1) - encoded_frames_->Set(); + encoded_frames_.Set(); } else { - encoded_frames_->Set(); + encoded_frames_.Set(); } } return test::FakeEncoder::Encode( @@ -2986,8 +3108,8 @@ TEST_F(EndToEndTest, RespectsNetworkState) { } bool sender_done = false; bool receiver_done = false; - while(!sender_done || !receiver_done) { - packet_event_->Wait(kSilenceTimeoutMs); + while (!sender_done || !receiver_done) { + packet_event_.Wait(kSilenceTimeoutMs); int64_t time_now_ms = clock_->TimeInMilliseconds(); rtc::CritScope lock(&test_crit_); if (sender_down) { @@ -3020,8 +3142,8 @@ TEST_F(EndToEndTest, RespectsNetworkState) { } rtc::CriticalSection test_crit_; - const rtc::scoped_ptr<EventWrapper> encoded_frames_; - const rtc::scoped_ptr<EventWrapper> packet_event_; + rtc::Event encoded_frames_; + rtc::Event packet_event_; Call* sender_call_; Call* receiver_call_; NetworkState sender_state_ GUARDED_BY(test_crit_); @@ -3031,7 +3153,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) { int down_frames_ GUARDED_BY(test_crit_); } test; - RunBaseTest(&test, FakeNetworkPipe::Config()); + RunBaseTest(&test); } TEST_F(EndToEndTest, CallReportsRttForSender) { @@ -3048,10 +3170,10 @@ TEST_F(EndToEndTest, CallReportsRttForSender) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateSendConfig(1, &sender_transport); + CreateSendConfig(1, 0, &sender_transport); CreateMatchingReceiveConfigs(&receiver_transport); - CreateStreams(); + CreateVideoStreams(); CreateFrameGeneratorCapturer(); Start(); @@ -3074,7 +3196,7 @@ TEST_F(EndToEndTest, CallReportsRttForSender) { TEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) { class UnusedEncoder : public test::FakeEncoder { - public: + public: UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {} int32_t Encode(const VideoFrame& input_image, const CodecSpecificInfo* codec_specific_info, @@ -3089,10 +3211,10 @@ TEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) { sender_call_->SignalNetworkState(kNetworkDown); UnusedTransport transport; - CreateSendConfig(1, &transport); + CreateSendConfig(1, 0, &transport); UnusedEncoder unused_encoder; - send_config_.encoder_settings.encoder = &unused_encoder; - CreateStreams(); + video_send_config_.encoder_settings.encoder = &unused_encoder; + CreateVideoStreams(); CreateFrameGeneratorCapturer(); Start(); @@ -3108,10 +3230,10 @@ TEST_F(EndToEndTest, NewReceiveStreamsRespectNetworkDown) { test::DirectTransport sender_transport(sender_call_.get()); sender_transport.SetReceiver(receiver_call_->Receiver()); - CreateSendConfig(1, &sender_transport); + CreateSendConfig(1, 0, &sender_transport); UnusedTransport transport; CreateMatchingReceiveConfigs(&transport); - CreateStreams(); + CreateVideoStreams(); CreateFrameGeneratorCapturer(); Start(); @@ -3168,4 +3290,76 @@ TEST_F(EndToEndTest, VerifyDefaultReceiveConfigParameters) { VerifyEmptyFecConfig(default_receive_config.rtp.fec); } +TEST_F(EndToEndTest, TransportSeqNumOnAudioAndVideo) { + static const int kExtensionId = 8; + class TransportSequenceNumberTest : public test::EndToEndTest { + public: + TransportSequenceNumberTest() + : EndToEndTest(kDefaultTimeoutMs), + video_observed_(false), + audio_observed_(false) { + parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber, + kExtensionId); + } + + size_t GetNumVideoStreams() const override { return 1; } + size_t GetNumAudioStreams() const override { return 1; } + + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStream::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { + send_config->rtp.extensions.clear(); + send_config->rtp.extensions.push_back( + RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); + (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions; + } + + void ModifyAudioConfigs( + AudioSendStream::Config* send_config, + std::vector<AudioReceiveStream::Config>* receive_configs) override { + send_config->rtp.extensions.clear(); + send_config->rtp.extensions.push_back( + RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); + (*receive_configs)[0].rtp.extensions.clear(); + (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions; + } + + Action OnSendRtp(const uint8_t* packet, size_t length) override { + RTPHeader header; + EXPECT_TRUE(parser_->Parse(packet, length, &header)); + EXPECT_TRUE(header.extension.hasTransportSequenceNumber); + // Unwrap packet id and verify uniqueness. + int64_t packet_id = + unwrapper_.Unwrap(header.extension.transportSequenceNumber); + EXPECT_TRUE(received_packet_ids_.insert(packet_id).second); + + if (header.ssrc == kVideoSendSsrcs[0]) + video_observed_ = true; + if (header.ssrc == kAudioSendSsrc) + audio_observed_ = true; + if (audio_observed_ && video_observed_ && + received_packet_ids_.size() == 50) { + size_t packet_id_range = + *received_packet_ids_.rbegin() - *received_packet_ids_.begin() + 1; + EXPECT_EQ(received_packet_ids_.size(), packet_id_range); + observation_complete_.Set(); + } + return SEND_PACKET; + } + + void PerformTest() override { + EXPECT_TRUE(Wait()) << "Timed out while waiting for audio and video " + "packets with transport sequence number."; + } + + private: + bool video_observed_; + bool audio_observed_; + SequenceNumberUnwrapper unwrapper_; + std::set<int64_t> received_packet_ids_; + } test; + + RunBaseTest(&test); +} } // namespace webrtc |