diff --git a/tools/valgrind-webrtc/gtest_exclude/video_engine_tests.gtest-drmemory_win32.txt b/tools/valgrind-webrtc/gtest_exclude/video_engine_tests.gtest-drmemory_win32.txt index bfc6b549a..6a213a245 100644 --- a/tools/valgrind-webrtc/gtest_exclude/video_engine_tests.gtest-drmemory_win32.txt +++ b/tools/valgrind-webrtc/gtest_exclude/video_engine_tests.gtest-drmemory_win32.txt @@ -1,6 +1,6 @@ # Never completes on Dr Memory Full. # https://code.google.com/p/webrtc/issues/detail?id=3159 -CallTest.SendsAndReceivesMultipleStreams -CallTest.ReceivesAndRetransmitsNack +EndToEndTest.SendsAndReceivesMultipleStreams +EndToEndTest.ReceivesAndRetransmitsNack # https://code.google.com/p/webrtc/issues/detail?id=3471 VideoSendStreamTest.RetransmitsNackOverRtxWithPacing diff --git a/tools/valgrind-webrtc/gtest_exclude/video_engine_tests.gtest-tsan.txt b/tools/valgrind-webrtc/gtest_exclude/video_engine_tests.gtest-tsan.txt deleted file mode 100644 index 6dab62515..000000000 --- a/tools/valgrind-webrtc/gtest_exclude/video_engine_tests.gtest-tsan.txt +++ /dev/null @@ -1,2 +0,0 @@ -# https://code.google.com/p/webrtc/issues/detail?id=2908 -CallTest.ReceivesAndRetransmitsNack diff --git a/webrtc/test/call_test.cc b/webrtc/test/call_test.cc new file mode 100644 index 000000000..ad2416f5e --- /dev/null +++ b/webrtc/test/call_test.cc @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "webrtc/test/call_test.h" + +#include "webrtc/test/encoder_settings.h" + +namespace webrtc { +namespace test { + +CallTest::CallTest() + : send_stream_(NULL), + receive_stream_(NULL), + fake_encoder_(Clock::GetRealTimeClock()) { +} +CallTest::~CallTest() { +} + +void CallTest::RunBaseTest(BaseTest* test) { + CreateSenderCall(test->GetSenderCallConfig()); + if (test->ShouldCreateReceivers()) + CreateReceiverCall(test->GetReceiverCallConfig()); + test->OnCallsCreated(sender_call_.get(), receiver_call_.get()); + + if (test->ShouldCreateReceivers()) { + test->SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); + } else { + // Sender-only call delivers to itself. + test->SetReceivers(sender_call_->Receiver(), NULL); + } + + CreateSendConfig(test->GetNumStreams()); + if (test->ShouldCreateReceivers()) { + CreateMatchingReceiveConfigs(); + } + test->ModifyConfigs(&send_config_, &receive_config_, &video_streams_); + CreateStreams(); + test->OnStreamsCreated(send_stream_, receive_stream_); + + CreateFrameGeneratorCapturer(); + test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get()); + + Start(); + test->PerformTest(); + test->StopSending(); + Stop(); + + DestroyStreams(); +} + +void CallTest::Start() { + send_stream_->Start(); + if (receive_stream_ != NULL) + receive_stream_->Start(); + frame_generator_capturer_->Start(); +} + +void CallTest::Stop() { + frame_generator_capturer_->Stop(); + if (receive_stream_ != NULL) + receive_stream_->Stop(); + send_stream_->Stop(); +} + +void CallTest::CreateCalls(const Call::Config& sender_config, + const Call::Config& receiver_config) { + CreateSenderCall(sender_config); + CreateReceiverCall(receiver_config); +} + +void CallTest::CreateSenderCall(const Call::Config& config) { + sender_call_.reset(Call::Create(config)); +} + +void CallTest::CreateReceiverCall(const Call::Config& config) { + receiver_call_.reset(Call::Create(config)); +} + +void CallTest::CreateSendConfig(size_t num_streams) { + assert(num_streams <= kNumSsrcs); + send_config_ = sender_call_->GetDefaultSendConfig(); + send_config_.encoder_settings.encoder = &fake_encoder_; + send_config_.encoder_settings.payload_name = "FAKE"; + send_config_.encoder_settings.payload_type = kFakeSendPayloadType; + video_streams_ = test::CreateVideoStreams(num_streams); + for (size_t i = 0; i < num_streams; ++i) + send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]); +} + +// TODO(pbos): Make receive configs into a vector. +void CallTest::CreateMatchingReceiveConfigs() { + assert(send_config_.rtp.ssrcs.size() == 1); + receive_config_ = receiver_call_->GetDefaultReceiveConfig(); + VideoCodec codec = + test::CreateDecoderVideoCodec(send_config_.encoder_settings); + receive_config_.codecs.push_back(codec); + if (send_config_.encoder_settings.encoder == &fake_encoder_) { + ExternalVideoDecoder decoder; + decoder.decoder = &fake_decoder_; + decoder.payload_type = send_config_.encoder_settings.payload_type; + receive_config_.external_decoders.push_back(decoder); + } + receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0]; + receive_config_.rtp.local_ssrc = kReceiverLocalSsrc; +} + +void CallTest::CreateFrameGeneratorCapturer() { + VideoStream stream = video_streams_.back(); + frame_generator_capturer_.reset( + test::FrameGeneratorCapturer::Create(send_stream_->Input(), + stream.width, + stream.height, + stream.max_framerate, + Clock::GetRealTimeClock())); +} +void CallTest::CreateStreams() { + assert(send_stream_ == NULL); + assert(receive_stream_ == NULL); + + send_stream_ = + sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL); + + if (receiver_call_.get() != NULL) + receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_); +} + +void CallTest::DestroyStreams() { + if (send_stream_ != NULL) + sender_call_->DestroyVideoSendStream(send_stream_); + if (receive_stream_ != NULL) + receiver_call_->DestroyVideoReceiveStream(receive_stream_); + send_stream_ = NULL; + receive_stream_ = NULL; +} + +const unsigned int CallTest::kDefaultTimeoutMs = 30 * 1000; +const unsigned int CallTest::kLongTimeoutMs = 120 * 1000; +const uint8_t CallTest::kSendPayloadType = 100; +const uint8_t CallTest::kFakeSendPayloadType = 125; +const uint8_t CallTest::kSendRtxPayloadType = 98; +const uint32_t CallTest::kSendRtxSsrc = 0xBADCAFE; +const uint32_t CallTest::kSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE, 0xC0FFEF}; +const uint32_t CallTest::kReceiverLocalSsrc = 0x123456; +const int CallTest::kNackRtpHistoryMs = 1000; + +BaseTest::BaseTest(unsigned int timeout_ms) : RtpRtcpObserver(timeout_ms) { +} + +BaseTest::BaseTest(unsigned int timeout_ms, + const FakeNetworkPipe::Config& config) + : RtpRtcpObserver(timeout_ms, config) { +} + +BaseTest::~BaseTest() { +} + +Call::Config BaseTest::GetSenderCallConfig() { + return Call::Config(SendTransport()); +} + +Call::Config BaseTest::GetReceiverCallConfig() { + return Call::Config(ReceiveTransport()); +} + +void BaseTest::OnCallsCreated(Call* sender_call, Call* receiver_call) { +} + +size_t BaseTest::GetNumStreams() const { + return 1; +} + +void BaseTest::ModifyConfigs(VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) { +} + +void BaseTest::OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) { +} + +void BaseTest::OnFrameGeneratorCapturerCreated( + FrameGeneratorCapturer* frame_generator_capturer) { +} + +SendTest::SendTest(unsigned int timeout_ms) : BaseTest(timeout_ms) { +} + +SendTest::SendTest(unsigned int timeout_ms, + const FakeNetworkPipe::Config& config) + : BaseTest(timeout_ms, config) { +} + +bool SendTest::ShouldCreateReceivers() const { + return false; +} + +EndToEndTest::EndToEndTest(unsigned int timeout_ms) : BaseTest(timeout_ms) { +} + +EndToEndTest::EndToEndTest(unsigned int timeout_ms, + const FakeNetworkPipe::Config& config) + : BaseTest(timeout_ms, config) { +} + +bool EndToEndTest::ShouldCreateReceivers() const { + return true; +} + +} // namespace test +} // namespace webrtc diff --git a/webrtc/test/call_test.h b/webrtc/test/call_test.h new file mode 100644 index 000000000..94ac2fabf --- /dev/null +++ b/webrtc/test/call_test.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#ifndef WEBRTC_TEST_COMMON_CALL_TEST_H_ +#define WEBRTC_TEST_COMMON_CALL_TEST_H_ + +#include + +#include "webrtc/call.h" +#include "webrtc/test/fake_decoder.h" +#include "webrtc/test/fake_encoder.h" +#include "webrtc/test/frame_generator_capturer.h" +#include "webrtc/test/rtp_rtcp_observer.h" + +namespace webrtc { +namespace test { + +class BaseTest; + +class CallTest : public ::testing::Test { + public: + CallTest(); + ~CallTest(); + + static const size_t kNumSsrcs = 3; + + static const unsigned int kDefaultTimeoutMs; + static const unsigned int kLongTimeoutMs; + static const uint8_t kSendPayloadType; + static const uint8_t kSendRtxPayloadType; + static const uint8_t kFakeSendPayloadType; + static const uint32_t kSendRtxSsrc; + static const uint32_t kSendSsrcs[kNumSsrcs]; + static const uint32_t kReceiverLocalSsrc; + static const int kNackRtpHistoryMs; + + protected: + void RunBaseTest(BaseTest* test); + + void CreateCalls(const Call::Config& sender_config, + const Call::Config& receiver_config); + void CreateSenderCall(const Call::Config& config); + void CreateReceiverCall(const Call::Config& config); + + void CreateSendConfig(size_t num_streams); + void CreateMatchingReceiveConfigs(); + + void CreateFrameGeneratorCapturer(); + + void CreateStreams(); + void Start(); + void Stop(); + void DestroyStreams(); + + scoped_ptr sender_call_; + VideoSendStream::Config send_config_; + std::vector video_streams_; + VideoSendStream* send_stream_; + + scoped_ptr receiver_call_; + VideoReceiveStream::Config receive_config_; + VideoReceiveStream* receive_stream_; + + scoped_ptr frame_generator_capturer_; + test::FakeEncoder fake_encoder_; + test::FakeDecoder fake_decoder_; +}; + +class BaseTest : public RtpRtcpObserver { + public: + explicit BaseTest(unsigned int timeout_ms); + BaseTest(unsigned int timeout_ms, const FakeNetworkPipe::Config& config); + virtual ~BaseTest(); + + virtual void PerformTest() = 0; + virtual bool ShouldCreateReceivers() const = 0; + + virtual size_t GetNumStreams() const; + + virtual Call::Config GetSenderCallConfig(); + virtual Call::Config GetReceiverCallConfig(); + virtual void OnCallsCreated(Call* sender_call, Call* receiver_call); + + virtual void ModifyConfigs(VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams); + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream); + + virtual void OnFrameGeneratorCapturerCreated( + FrameGeneratorCapturer* frame_generator_capturer); +}; + +class SendTest : public BaseTest { + public: + explicit SendTest(unsigned int timeout_ms); + SendTest(unsigned int timeout_ms, const FakeNetworkPipe::Config& config); + + virtual bool ShouldCreateReceivers() const OVERRIDE; +}; + +class EndToEndTest : public BaseTest { + public: + explicit EndToEndTest(unsigned int timeout_ms); + EndToEndTest(unsigned int timeout_ms, const FakeNetworkPipe::Config& config); + + virtual bool ShouldCreateReceivers() const OVERRIDE; +}; + +} // namespace test +} // namespace webrtc + +#endif // WEBRTC_TEST_COMMON_CALL_TEST_H_ diff --git a/webrtc/test/rtp_rtcp_observer.h b/webrtc/test/rtp_rtcp_observer.h index e4486534c..670a29def 100644 --- a/webrtc/test/rtp_rtcp_observer.h +++ b/webrtc/test/rtp_rtcp_observer.h @@ -16,6 +16,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/test/direct_transport.h" #include "webrtc/typedefs.h" #include "webrtc/video_send_stream.h" diff --git a/webrtc/test/webrtc_test_common.gyp b/webrtc/test/webrtc_test_common.gyp index 556a44501..8c8774fba 100644 --- a/webrtc/test/webrtc_test_common.gyp +++ b/webrtc/test/webrtc_test_common.gyp @@ -14,6 +14,8 @@ 'target_name': 'webrtc_test_common', 'type': 'static_library', 'sources': [ + 'call_test.cc', + 'call_test.h', 'configurable_frame_size_encoder.cc', 'configurable_frame_size_encoder.h', 'direct_transport.cc', @@ -54,10 +56,11 @@ 'dependencies': [ '<(DEPTH)/testing/gtest.gyp:gtest', '<(DEPTH)/third_party/gflags/gflags.gyp:gflags', - '<(webrtc_root)/modules/modules.gyp:video_capture_module', '<(webrtc_root)/modules/modules.gyp:media_file', + '<(webrtc_root)/modules/modules.gyp:video_capture_module', '<(webrtc_root)/test/test.gyp:frame_generator', '<(webrtc_root)/test/test.gyp:test_support', + '<(webrtc_root)/webrtc.gyp:webrtc', ], }, { diff --git a/webrtc/video/bitrate_estimator_tests.cc b/webrtc/video/bitrate_estimator_tests.cc index f8b9060f6..d21de179f 100644 --- a/webrtc/video/bitrate_estimator_tests.cc +++ b/webrtc/video/bitrate_estimator_tests.cc @@ -19,6 +19,7 @@ #include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/system_wrappers/interface/thread_annotations.h" #include "webrtc/system_wrappers/interface/trace.h" +#include "webrtc/test/call_test.h" #include "webrtc/test/direct_transport.h" #include "webrtc/test/encoder_settings.h" #include "webrtc/test/fake_decoder.h" @@ -30,12 +31,7 @@ namespace webrtc { static const int kTOFExtensionId = 4; static const int kASTExtensionId = 5; -static unsigned int kDefaultTimeoutMs = 30 * 1000; -static const uint32_t kSendSsrc = 0x654321; -static const uint32_t kReceiverLocalSsrc = 0x123456; -static const uint8_t kSendPayloadType = 125; - -class BitrateEstimatorTest : public ::testing::Test { +class BitrateEstimatorTest : public test::CallTest { public: BitrateEstimatorTest() : receiver_trace_(), @@ -43,7 +39,6 @@ class BitrateEstimatorTest : public ::testing::Test { receive_transport_(), sender_call_(), receiver_call_(), - send_config_(), receive_config_(), streams_() { } @@ -68,11 +63,11 @@ class BitrateEstimatorTest : public ::testing::Test { receive_transport_.SetReceiver(sender_call_->Receiver()); send_config_ = sender_call_->GetDefaultSendConfig(); - send_config_.rtp.ssrcs.push_back(kSendSsrc); + send_config_.rtp.ssrcs.push_back(kSendSsrcs[0]); // Encoders will be set separately per stream. send_config_.encoder_settings.encoder = NULL; send_config_.encoder_settings.payload_name = "FAKE"; - send_config_.encoder_settings.payload_type = kSendPayloadType; + send_config_.encoder_settings.payload_type = kFakeSendPayloadType; video_streams_ = test::CreateVideoStreams(1); receive_config_ = receiver_call_->GetDefaultReceiveConfig(); @@ -228,8 +223,6 @@ class BitrateEstimatorTest : public ::testing::Test { test::DirectTransport receive_transport_; scoped_ptr sender_call_; scoped_ptr receiver_call_; - VideoSendStream::Config send_config_; - std::vector video_streams_; VideoReceiveStream::Config receive_config_; std::vector streams_; }; diff --git a/webrtc/video/call_perf_tests.cc b/webrtc/video/call_perf_tests.cc index fa3f2388c..b6e2b3408 100644 --- a/webrtc/video/call_perf_tests.cc +++ b/webrtc/video/call_perf_tests.cc @@ -23,6 +23,7 @@ #include "webrtc/system_wrappers/interface/rtp_to_ntp.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/system_wrappers/interface/thread_annotations.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" @@ -42,61 +43,20 @@ namespace webrtc { -static unsigned int kLongTimeoutMs = 120 * 1000; -static const uint32_t kSendSsrc = 0x654321; -static const uint32_t kReceiverLocalSsrc = 0x123456; -static const uint8_t kSendPayloadType = 125; - -class CallPerfTest : public ::testing::Test { - public: - CallPerfTest() - : send_stream_(NULL), fake_encoder_(Clock::GetRealTimeClock()) {} - +class CallPerfTest : public test::CallTest { protected: - void CreateTestConfig(Call* call) { - send_config_ = call->GetDefaultSendConfig(); - send_config_.rtp.ssrcs.push_back(kSendSsrc); - send_config_.encoder_settings.encoder = &fake_encoder_; - send_config_.encoder_settings.payload_type = kSendPayloadType; - send_config_.encoder_settings.payload_name = "FAKE"; - video_streams_ = test::CreateVideoStreams(1); - } - - void RunVideoSendTest(Call* call, - const VideoSendStream::Config& config, - test::RtpRtcpObserver* observer) { - send_stream_ = call->CreateVideoSendStream(config, video_streams_, NULL); - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create( - send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); - send_stream_->Start(); - frame_generator_capturer->Start(); - - EXPECT_EQ(kEventSignaled, observer->Wait()); - - observer->StopSending(); - frame_generator_capturer->Stop(); - send_stream_->Stop(); - call->DestroyVideoSendStream(send_stream_); - } - void TestMinTransmitBitrate(bool pad_to_min_bitrate); void TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config, int threshold_ms, int start_time_ms, int run_time_ms); - - VideoSendStream::Config send_config_; - std::vector video_streams_; - VideoSendStream* send_stream_; - test::FakeEncoder fake_encoder_; }; class SyncRtcpObserver : public test::RtpRtcpObserver { public: explicit SyncRtcpObserver(const FakeNetworkPipe::Config& config) - : test::RtpRtcpObserver(kLongTimeoutMs, config), + : test::RtpRtcpObserver(CallPerfTest::kLongTimeoutMs, config), crit_(CriticalSectionWrapper::CreateCriticalSection()) {} virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { @@ -226,6 +186,31 @@ class VideoRtcpAndSyncObserver : public SyncRtcpObserver, public VideoRenderer { }; TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSync) { + class AudioPacketReceiver : public PacketReceiver { + public: + AudioPacketReceiver(int channel, VoENetwork* voe_network) + : channel_(channel), + voe_network_(voe_network), + parser_(RtpHeaderParser::Create()) {} + virtual DeliveryStatus DeliverPacket(const uint8_t* packet, + size_t length) OVERRIDE { + int ret; + if (parser_->IsRtcp(packet, static_cast(length))) { + ret = voe_network_->ReceivedRTCPPacket( + channel_, packet, static_cast(length)); + } else { + ret = voe_network_->ReceivedRTPPacket( + channel_, packet, static_cast(length), PacketTime()); + } + return ret == 0 ? DELIVERY_OK : DELIVERY_PACKET_ERROR; + } + + private: + int channel_; + VoENetwork* voe_network_; + scoped_ptr parser_; + }; + VoiceEngine* voice_engine = VoiceEngine::Create(); VoEBase* voe_base = VoEBase::GetInterface(voice_engine); VoECodec* voe_codec = VoECodec::GetInterface(voice_engine); @@ -249,37 +234,12 @@ TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSync) { Call::Config receiver_config(observer.ReceiveTransport()); receiver_config.voice_engine = voice_engine; - scoped_ptr sender_call( - Call::Create(Call::Config(observer.SendTransport()))); - scoped_ptr receiver_call(Call::Create(receiver_config)); + CreateCalls(Call::Config(observer.SendTransport()), receiver_config); + CodecInst isac = {103, "ISAC", 16000, 480, 1, 32000}; EXPECT_EQ(0, voe_codec->SetSendCodec(channel, isac)); - class VoicePacketReceiver : public PacketReceiver { - public: - VoicePacketReceiver(int channel, VoENetwork* voe_network) - : channel_(channel), - voe_network_(voe_network), - parser_(RtpHeaderParser::Create()) {} - virtual DeliveryStatus DeliverPacket(const uint8_t* packet, - size_t length) OVERRIDE { - int ret; - if (parser_->IsRtcp(packet, static_cast(length))) { - ret = voe_network_->ReceivedRTCPPacket( - channel_, packet, static_cast(length)); - } else { - ret = voe_network_->ReceivedRTPPacket( - channel_, packet, static_cast(length), PacketTime()); - } - return ret == 0 ? DELIVERY_OK : DELIVERY_PACKET_ERROR; - } - - private: - int channel_; - VoENetwork* voe_network_; - scoped_ptr parser_; - } voe_packet_receiver(channel, voe_network); - + AudioPacketReceiver voe_packet_receiver(channel, voe_network); audio_observer.SetReceivers(&voe_packet_receiver, &voe_packet_receiver); internal::TransportAdapter transport_adapter(audio_observer.SendTransport()); @@ -287,41 +247,21 @@ TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSync) { EXPECT_EQ(0, voe_network->RegisterExternalTransport(channel, transport_adapter)); - observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver()); + observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); test::FakeDecoder fake_decoder; - CreateTestConfig(sender_call.get()); + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); - VideoReceiveStream::Config receive_config = - receiver_call->GetDefaultReceiveConfig(); - assert(receive_config.codecs.empty()); - VideoCodec codec = - test::CreateDecoderVideoCodec(send_config_.encoder_settings); - receive_config.codecs.push_back(codec); - assert(receive_config.external_decoders.empty()); - ExternalVideoDecoder decoder; - decoder.decoder = &fake_decoder; - decoder.payload_type = send_config_.encoder_settings.payload_type; - receive_config.external_decoders.push_back(decoder); - receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0]; - receive_config.rtp.local_ssrc = kReceiverLocalSsrc; - receive_config.renderer = &observer; - receive_config.audio_channel_id = channel; + receive_config_.renderer = &observer; + receive_config_.audio_channel_id = channel; - VideoSendStream* send_stream = - sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL); - VideoReceiveStream* receive_stream = - receiver_call->CreateVideoReceiveStream(receive_config); - scoped_ptr capturer( - test::FrameGeneratorCapturer::Create(send_stream->Input(), - video_streams_[0].width, - video_streams_[0].height, - 30, - Clock::GetRealTimeClock())); - receive_stream->Start(); - send_stream->Start(); - capturer->Start(); + CreateStreams(); + + CreateFrameGeneratorCapturer(); + + Start(); fake_audio_device.Start(); EXPECT_EQ(0, voe_base->StartPlayout(channel)); @@ -336,9 +276,7 @@ TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSync) { EXPECT_EQ(0, voe_base->StopPlayout(channel)); fake_audio_device.Stop(); - capturer->Stop(); - send_stream->Stop(); - receive_stream->Stop(); + Stop(); observer.StopSending(); audio_observer.StopSending(); @@ -347,174 +285,126 @@ TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSync) { voe_codec->Release(); voe_network->Release(); voe_sync->Release(); - sender_call->DestroyVideoSendStream(send_stream); - receiver_call->DestroyVideoReceiveStream(receive_stream); + + DestroyStreams(); + VoiceEngine::Delete(voice_engine); } -class CaptureNtpTimeObserver : public test::RtpRtcpObserver, - public VideoRenderer { - public: - CaptureNtpTimeObserver(Clock* clock, - const FakeNetworkPipe::Config& config, - int threshold_ms, - int start_time_ms, - int run_time_ms) - : RtpRtcpObserver(kLongTimeoutMs, config), - clock_(clock), - threshold_ms_(threshold_ms), - start_time_ms_(start_time_ms), - run_time_ms_(run_time_ms), - creation_time_ms_(clock_->TimeInMilliseconds()), - capturer_(NULL), - rtp_start_timestamp_set_(false), - rtp_start_timestamp_(0) {} - - virtual void RenderFrame(const I420VideoFrame& video_frame, - int time_to_render_ms) OVERRIDE { - if (video_frame.ntp_time_ms() <= 0) { - // Haven't got enough RTCP SR in order to calculate the capture ntp time. - return; - } - - int64_t now_ms = clock_->TimeInMilliseconds(); - int64_t time_since_creation = now_ms - creation_time_ms_; - if (time_since_creation < start_time_ms_) { - // Wait for |start_time_ms_| before start measuring. - return; - } - - if (time_since_creation > run_time_ms_) { - observation_complete_->Set(); - } - - FrameCaptureTimeList::iterator iter = - capture_time_list_.find(video_frame.timestamp()); - EXPECT_TRUE(iter != capture_time_list_.end()); - - // The real capture time has been wrapped to uint32_t before converted - // to rtp timestamp in the sender side. So here we convert the estimated - // capture time to a uint32_t 90k timestamp also for comparing. - uint32_t estimated_capture_timestamp = - 90 * static_cast(video_frame.ntp_time_ms()); - uint32_t real_capture_timestamp = iter->second; - int time_offset_ms = real_capture_timestamp - estimated_capture_timestamp; - time_offset_ms = time_offset_ms / 90; - std::stringstream ss; - ss << time_offset_ms; - - webrtc::test::PrintResult("capture_ntp_time", - "", - "real - estimated", - ss.str(), - "ms", - true); - EXPECT_TRUE(std::abs(time_offset_ms) < threshold_ms_); - } - - virtual Action OnSendRtp(const uint8_t* packet, size_t length) { - RTPHeader header; - EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); - - if (!rtp_start_timestamp_set_) { - // Calculate the rtp timestamp offset in order to calculate the real - // capture time. - uint32_t first_capture_timestamp = - 90 * static_cast(capturer_->first_frame_capture_time()); - rtp_start_timestamp_ = header.timestamp - first_capture_timestamp; - rtp_start_timestamp_set_ = true; - } - - uint32_t capture_timestamp = header.timestamp - rtp_start_timestamp_; - capture_time_list_.insert(capture_time_list_.end(), - std::make_pair(header.timestamp, - capture_timestamp)); - return SEND_PACKET; - } - - void SetCapturer(test::FrameGeneratorCapturer* capturer) { - capturer_ = capturer; - } - - private: - Clock* clock_; - int threshold_ms_; - int start_time_ms_; - int run_time_ms_; - int64_t creation_time_ms_; - test::FrameGeneratorCapturer* capturer_; - bool rtp_start_timestamp_set_; - uint32_t rtp_start_timestamp_; - typedef std::map FrameCaptureTimeList; - FrameCaptureTimeList capture_time_list_; -}; - void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config, int threshold_ms, int start_time_ms, int run_time_ms) { - CaptureNtpTimeObserver observer(Clock::GetRealTimeClock(), - net_config, - threshold_ms, - start_time_ms, - run_time_ms); + class CaptureNtpTimeObserver : public test::EndToEndTest, + public VideoRenderer { + public: + CaptureNtpTimeObserver(const FakeNetworkPipe::Config& config, + int threshold_ms, + int start_time_ms, + int run_time_ms) + : EndToEndTest(kLongTimeoutMs, config), + clock_(Clock::GetRealTimeClock()), + threshold_ms_(threshold_ms), + start_time_ms_(start_time_ms), + run_time_ms_(run_time_ms), + creation_time_ms_(clock_->TimeInMilliseconds()), + capturer_(NULL), + rtp_start_timestamp_set_(false), + rtp_start_timestamp_(0) {} - // Sender/receiver call. - Call::Config receiver_config(observer.ReceiveTransport()); - scoped_ptr receiver_call(Call::Create(receiver_config)); - scoped_ptr sender_call( - Call::Create(Call::Config(observer.SendTransport()))); - observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver()); + private: + virtual void RenderFrame(const I420VideoFrame& video_frame, + int time_to_render_ms) OVERRIDE { + if (video_frame.ntp_time_ms() <= 0) { + // Haven't got enough RTCP SR in order to calculate the capture ntp + // time. + return; + } - // Configure send stream. - CreateTestConfig(sender_call.get()); - VideoSendStream* send_stream = - sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL); - scoped_ptr capturer( - test::FrameGeneratorCapturer::Create(send_stream->Input(), - video_streams_[0].width, - video_streams_[0].height, - 30, - Clock::GetRealTimeClock())); - observer.SetCapturer(capturer.get()); + int64_t now_ms = clock_->TimeInMilliseconds(); + int64_t time_since_creation = now_ms - creation_time_ms_; + if (time_since_creation < start_time_ms_) { + // Wait for |start_time_ms_| before start measuring. + return; + } - // Configure receive stream. - VideoReceiveStream::Config receive_config = - receiver_call->GetDefaultReceiveConfig(); - assert(receive_config.codecs.empty()); - VideoCodec codec = - test::CreateDecoderVideoCodec(send_config_.encoder_settings); - receive_config.codecs.push_back(codec); - assert(receive_config.external_decoders.empty()); - ExternalVideoDecoder decoder; - test::FakeDecoder fake_decoder; - decoder.decoder = &fake_decoder; - decoder.payload_type = send_config_.encoder_settings.payload_type; - receive_config.external_decoders.push_back(decoder); - receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0]; - receive_config.rtp.local_ssrc = kReceiverLocalSsrc; - receive_config.renderer = &observer; - // Enable the receiver side rtt calculation. - receive_config.rtp.rtcp_xr.receiver_reference_time_report = true; - VideoReceiveStream* receive_stream = - receiver_call->CreateVideoReceiveStream(receive_config); + if (time_since_creation > run_time_ms_) { + observation_complete_->Set(); + } - // Start the test - receive_stream->Start(); - send_stream->Start(); - capturer->Start(); + FrameCaptureTimeList::iterator iter = + capture_time_list_.find(video_frame.timestamp()); + EXPECT_TRUE(iter != capture_time_list_.end()); - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while waiting for estimated capture ntp time to be " - << "within bounds."; + // The real capture time has been wrapped to uint32_t before converted + // to rtp timestamp in the sender side. So here we convert the estimated + // capture time to a uint32_t 90k timestamp also for comparing. + uint32_t estimated_capture_timestamp = + 90 * static_cast(video_frame.ntp_time_ms()); + uint32_t real_capture_timestamp = iter->second; + int time_offset_ms = real_capture_timestamp - estimated_capture_timestamp; + time_offset_ms = time_offset_ms / 90; + std::stringstream ss; + ss << time_offset_ms; - capturer->Stop(); - send_stream->Stop(); - receive_stream->Stop(); - observer.StopSending(); + webrtc::test::PrintResult( + "capture_ntp_time", "", "real - estimated", ss.str(), "ms", true); + EXPECT_TRUE(std::abs(time_offset_ms) < threshold_ms_); + } - sender_call->DestroyVideoSendStream(send_stream); - receiver_call->DestroyVideoReceiveStream(receive_stream); + virtual Action OnSendRtp(const uint8_t* packet, size_t length) { + RTPHeader header; + EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); + + if (!rtp_start_timestamp_set_) { + // Calculate the rtp timestamp offset in order to calculate the real + // capture time. + uint32_t first_capture_timestamp = + 90 * static_cast(capturer_->first_frame_capture_time()); + rtp_start_timestamp_ = header.timestamp - first_capture_timestamp; + rtp_start_timestamp_set_ = true; + } + + uint32_t capture_timestamp = header.timestamp - rtp_start_timestamp_; + capture_time_list_.insert( + capture_time_list_.end(), + std::make_pair(header.timestamp, capture_timestamp)); + return SEND_PACKET; + } + + virtual void OnFrameGeneratorCapturerCreated( + test::FrameGeneratorCapturer* frame_generator_capturer) OVERRIDE { + capturer_ = frame_generator_capturer; + } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + receive_config->renderer = this; + // Enable the receiver side rtt calculation. + receive_config->rtp.rtcp_xr.receiver_reference_time_report = true; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for " + "estimated capture NTP time to be " + "within bounds."; + } + + Clock* clock_; + int threshold_ms_; + int start_time_ms_; + int run_time_ms_; + int64_t creation_time_ms_; + test::FrameGeneratorCapturer* capturer_; + bool rtp_start_timestamp_set_; + uint32_t rtp_start_timestamp_; + typedef std::map FrameCaptureTimeList; + FrameCaptureTimeList capture_time_list_; + } test(net_config, threshold_ms, start_time_ms, run_time_ms); + + RunBaseTest(&test); } TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkDelay) { @@ -542,26 +432,32 @@ TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkJitter) { TEST_F(CallPerfTest, RegisterCpuOveruseObserver) { // Verifies that either a normal or overuse callback is triggered. - class OveruseCallbackObserver : public test::RtpRtcpObserver, + class OveruseCallbackObserver : public test::SendTest, public webrtc::OveruseCallback { public: - OveruseCallbackObserver() : RtpRtcpObserver(kLongTimeoutMs) {} + OveruseCallbackObserver() : SendTest(kLongTimeoutMs) {} virtual void OnOveruse() OVERRIDE { observation_complete_->Set(); } + virtual void OnNormalUse() OVERRIDE { observation_complete_->Set(); } - }; - OveruseCallbackObserver observer; - Call::Config call_config(observer.SendTransport()); - call_config.overuse_callback = &observer; - scoped_ptr call(Call::Create(call_config)); + virtual Call::Config GetSenderCallConfig() OVERRIDE { + Call::Config config(SendTransport()); + config.overuse_callback = this; + return config; + } - CreateTestConfig(call.get()); - RunVideoSendTest(call.get(), send_config_, &observer); + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out before receiving an overuse callback."; + } + } test; + + RunBaseTest(&test); } void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { @@ -570,15 +466,16 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { static const int kMinAcceptableTransmitBitrate = 130; static const int kMaxAcceptableTransmitBitrate = 170; static const int kNumBitrateObservationsInRange = 100; - class BitrateObserver : public test::RtpRtcpObserver, public PacketReceiver { + class BitrateObserver : public test::EndToEndTest, public PacketReceiver { public: explicit BitrateObserver(bool using_min_transmit_bitrate) - : test::RtpRtcpObserver(kLongTimeoutMs), + : EndToEndTest(kLongTimeoutMs), send_stream_(NULL), send_transport_receiver_(NULL), - using_min_transmit_bitrate_(using_min_transmit_bitrate), + pad_to_min_bitrate_(using_min_transmit_bitrate), num_bitrate_observations_in_range_(0) {} + private: virtual void SetReceivers(PacketReceiver* send_transport_receiver, PacketReceiver* receive_transport_receiver) OVERRIDE { @@ -586,11 +483,6 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { test::RtpRtcpObserver::SetReceivers(this, receive_transport_receiver); } - void SetSendStream(VideoSendStream* send_stream) { - send_stream_ = send_stream; - } - - private: virtual DeliveryStatus DeliverPacket(const uint8_t* packet, size_t length) OVERRIDE { VideoSendStream::Stats stats = send_stream_->GetStats(); @@ -600,13 +492,13 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { if (bitrate_kbps > 0) { test::PrintResult( "bitrate_stats_", - (using_min_transmit_bitrate_ ? "min_transmit_bitrate" - : "without_min_transmit_bitrate"), + (pad_to_min_bitrate_ ? "min_transmit_bitrate" + : "without_min_transmit_bitrate"), "bitrate_kbps", static_cast(bitrate_kbps), "kbps", false); - if (using_min_transmit_bitrate_) { + if (pad_to_min_bitrate_) { if (bitrate_kbps > kMinAcceptableTransmitBitrate && bitrate_kbps < kMaxAcceptableTransmitBitrate) { ++num_bitrate_observations_in_range_; @@ -626,66 +518,35 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { return send_transport_receiver_->DeliverPacket(packet, length); } + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) { + send_stream_ = send_stream; + } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + if (pad_to_min_bitrate_) { + send_config->rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps; + } else { + assert(send_config->rtp.min_transmit_bitrate_bps == 0); + } + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timeout while waiting for send-bitrate stats."; + } + VideoSendStream* send_stream_; PacketReceiver* send_transport_receiver_; - const bool using_min_transmit_bitrate_; + const bool pad_to_min_bitrate_; int num_bitrate_observations_in_range_; - } observer(pad_to_min_bitrate); + } test(pad_to_min_bitrate); - scoped_ptr sender_call( - Call::Create(Call::Config(observer.SendTransport()))); - scoped_ptr receiver_call( - Call::Create(Call::Config(observer.ReceiveTransport()))); - - CreateTestConfig(sender_call.get()); fake_encoder_.SetMaxBitrate(kMaxEncodeBitrateKbps); - - observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver()); - - if (pad_to_min_bitrate) { - send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps; - } else { - assert(send_config_.rtp.min_transmit_bitrate_bps == 0); - } - - VideoReceiveStream::Config receive_config = - receiver_call->GetDefaultReceiveConfig(); - receive_config.codecs.clear(); - VideoCodec codec = - test::CreateDecoderVideoCodec(send_config_.encoder_settings); - receive_config.codecs.push_back(codec); - test::FakeDecoder fake_decoder; - ExternalVideoDecoder decoder; - decoder.decoder = &fake_decoder; - decoder.payload_type = send_config_.encoder_settings.payload_type; - receive_config.external_decoders.push_back(decoder); - receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0]; - receive_config.rtp.local_ssrc = kReceiverLocalSsrc; - - VideoSendStream* send_stream = - sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL); - VideoReceiveStream* receive_stream = - receiver_call->CreateVideoReceiveStream(receive_config); - scoped_ptr capturer( - test::FrameGeneratorCapturer::Create(send_stream->Input(), - video_streams_[0].width, - video_streams_[0].height, - 30, - Clock::GetRealTimeClock())); - observer.SetSendStream(send_stream); - receive_stream->Start(); - send_stream->Start(); - capturer->Start(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timeout while waiting for send-bitrate stats."; - - send_stream->Stop(); - receive_stream->Stop(); - observer.StopSending(); - capturer->Stop(); - sender_call->DestroyVideoSendStream(send_stream); - receiver_call->DestroyVideoReceiveStream(receive_stream); + RunBaseTest(&test); } TEST_F(CallPerfTest, PadsToMinTransmitBitrate) { TestMinTransmitBitrate(true); } diff --git a/webrtc/video/call_tests.cc b/webrtc/video/end_to_end_tests.cc similarity index 55% rename from webrtc/video/call_tests.cc rename to webrtc/video/end_to_end_tests.cc index 5bcf11576..0f6f2dced 100644 --- a/webrtc/video/call_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -24,6 +24,7 @@ #include "webrtc/system_wrappers/interface/event_wrapper.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/system_wrappers/interface/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" @@ -39,66 +40,19 @@ namespace webrtc { -static unsigned int kDefaultTimeoutMs = 30 * 1000; -static unsigned int kLongTimeoutMs = 120 * 1000; -static const uint32_t kSendSsrc = 0x654321; -static const uint32_t kSendRtxSsrc = 0x424242; -static const uint32_t kReceiverLocalSsrc = 0x123456; -static const uint8_t kSendPayloadType = 125; -static const uint8_t kSendRtxPayloadType = 126; static const int kRedPayloadType = 118; static const int kUlpfecPayloadType = 119; -class CallTest : public ::testing::Test { +class EndToEndTest : public test::CallTest { public: - CallTest() - : send_stream_(NULL), - receive_stream_(NULL), - fake_encoder_(Clock::GetRealTimeClock()) {} + EndToEndTest() {} - virtual ~CallTest() { + virtual ~EndToEndTest() { EXPECT_EQ(NULL, send_stream_); EXPECT_EQ(NULL, receive_stream_); } protected: - void CreateCalls(const Call::Config& sender_config, - const Call::Config& receiver_config) { - sender_call_.reset(Call::Create(sender_config)); - receiver_call_.reset(Call::Create(receiver_config)); - } - - void CreateTestConfigs() { - send_config_ = sender_call_->GetDefaultSendConfig(); - receive_config_ = receiver_call_->GetDefaultReceiveConfig(); - - send_config_.rtp.ssrcs.push_back(kSendSsrc); - send_config_.encoder_settings.encoder = &fake_encoder_; - send_config_.encoder_settings.payload_name = "FAKE"; - send_config_.encoder_settings.payload_type = kSendPayloadType; - video_streams_ = test::CreateVideoStreams(1); - - assert(receive_config_.codecs.empty()); - VideoCodec codec = - test::CreateDecoderVideoCodec(send_config_.encoder_settings); - receive_config_.codecs.push_back(codec); - ExternalVideoDecoder decoder; - decoder.decoder = &fake_decoder_; - decoder.payload_type = send_config_.encoder_settings.payload_type; - receive_config_.external_decoders.push_back(decoder); - receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0]; - receive_config_.rtp.local_ssrc = kReceiverLocalSsrc; - } - - void CreateStreams() { - assert(send_stream_ == NULL); - assert(receive_stream_ == NULL); - - send_stream_ = - sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL); - receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_); - } - void CreateFrameGenerator() { frame_generator_capturer_.reset( test::FrameGeneratorCapturer::Create(send_stream_->Input(), @@ -124,113 +78,19 @@ class CallTest : public ::testing::Test { receive_stream_->Stop(); } - void DestroyStreams() { - if (send_stream_ != NULL) - sender_call_->DestroyVideoSendStream(send_stream_); - if (receive_stream_ != NULL) - receiver_call_->DestroyVideoReceiveStream(receive_stream_); - send_stream_ = NULL; - receive_stream_ = NULL; - } - void DecodesRetransmittedFrame(bool retransmit_over_rtx); void ReceivesPliAndRecovers(int rtp_history_ms); void RespectsRtcpMode(newapi::RtcpMode rtcp_mode); void TestXrReceiverReferenceTimeReport(bool enable_rrtr); - - scoped_ptr sender_call_; - scoped_ptr receiver_call_; - - VideoSendStream::Config send_config_; - std::vector video_streams_; - VideoReceiveStream::Config receive_config_; - - VideoSendStream* send_stream_; - VideoReceiveStream* receive_stream_; - - scoped_ptr frame_generator_capturer_; - - test::FakeEncoder fake_encoder_; - test::FakeDecoder fake_decoder_; }; -class NackObserver : public test::RtpRtcpObserver { - static const int kNumberOfNacksToObserve = 2; - static const int kLossBurstSize = 2; - static const int kPacketsBetweenLossBursts = 9; - - public: - NackObserver() - : test::RtpRtcpObserver(kLongTimeoutMs), - rtp_parser_(RtpHeaderParser::Create()), - sent_rtp_packets_(0), - packets_left_to_drop_(0), - nacks_left_(kNumberOfNacksToObserve) {} - - private: - virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { - RTPHeader header; - EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast(length), &header)); - - // Never drop retransmitted packets. - if (dropped_packets_.find(header.sequenceNumber) != - dropped_packets_.end()) { - retransmitted_packets_.insert(header.sequenceNumber); - if (nacks_left_ == 0 && - retransmitted_packets_.size() == dropped_packets_.size()) { - observation_complete_->Set(); - } - return SEND_PACKET; - } - - ++sent_rtp_packets_; - - // Enough NACKs received, stop dropping packets. - if (nacks_left_ == 0) - return SEND_PACKET; - - // Check if it's time for a new loss burst. - if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0) - packets_left_to_drop_ = kLossBurstSize; - - if (packets_left_to_drop_ > 0) { - --packets_left_to_drop_; - dropped_packets_.insert(header.sequenceNumber); - return DROP_PACKET; - } - - return SEND_PACKET; - } - - virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { - RTCPUtility::RTCPParserV2 parser(packet, length, true); - EXPECT_TRUE(parser.IsValid()); - - RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) { - --nacks_left_; - break; - } - packet_type = parser.Iterate(); - } - return SEND_PACKET; - } - - private: - scoped_ptr rtp_parser_; - std::set dropped_packets_; - std::set retransmitted_packets_; - uint64_t sent_rtp_packets_; - int packets_left_to_drop_; - int nacks_left_; -}; - -TEST_F(CallTest, ReceiverCanBeStartedTwice) { +TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) { test::NullTransport transport; CreateCalls(Call::Config(&transport), Call::Config(&transport)); - CreateTestConfigs(); + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); + CreateStreams(); receive_stream_->Start(); @@ -239,11 +99,13 @@ TEST_F(CallTest, ReceiverCanBeStartedTwice) { DestroyStreams(); } -TEST_F(CallTest, ReceiverCanBeStoppedTwice) { +TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) { test::NullTransport transport; CreateCalls(Call::Config(&transport), Call::Config(&transport)); - CreateTestConfigs(); + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); + CreateStreams(); receive_stream_->Stop(); @@ -252,7 +114,7 @@ TEST_F(CallTest, ReceiverCanBeStoppedTwice) { DestroyStreams(); } -TEST_F(CallTest, RendersSingleDelayedFrame) { +TEST_F(EndToEndTest, RendersSingleDelayedFrame) { static const int kWidth = 320; static const int kHeight = 240; // This constant is chosen to be higher than the timeout in the video_render @@ -297,7 +159,8 @@ TEST_F(CallTest, RendersSingleDelayedFrame) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateTestConfigs(); + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); TestFrameCallback pre_render_callback; receive_config_.pre_render_callback = &pre_render_callback; @@ -324,7 +187,7 @@ TEST_F(CallTest, RendersSingleDelayedFrame) { DestroyStreams(); } -TEST_F(CallTest, TransmitsFirstFrame) { +TEST_F(EndToEndTest, TransmitsFirstFrame) { class Renderer : public VideoRenderer { public: Renderer() : event_(EventWrapper::Create()) {} @@ -347,7 +210,8 @@ TEST_F(CallTest, TransmitsFirstFrame) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateTestConfigs(); + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); receive_config_.renderer = &renderer; CreateStreams(); @@ -368,10 +232,10 @@ TEST_F(CallTest, TransmitsFirstFrame) { DestroyStreams(); } -TEST_F(CallTest, ReceiverUsesLocalSsrc) { - class SyncRtcpObserver : public test::RtpRtcpObserver { +TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) { + class SyncRtcpObserver : public test::EndToEndTest { public: - SyncRtcpObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {} + SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {} virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { @@ -387,63 +251,112 @@ TEST_F(CallTest, ReceiverUsesLocalSsrc) { return SEND_PACKET; } - } observer; - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for a receiver RTCP packet to be sent."; + } + } test; - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - - CreateTestConfigs(); - - CreateStreams(); - CreateFrameGenerator(); - StartSending(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while waiting for a receiver RTCP packet to be sent."; - - StopSending(); - - observer.StopSending(); - - DestroyStreams(); + RunBaseTest(&test); } -TEST_F(CallTest, ReceivesAndRetransmitsNack) { - NackObserver observer; +TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { + static const int kNumberOfNacksToObserve = 2; + static const int kLossBurstSize = 2; + static const int kPacketsBetweenLossBursts = 9; + class NackObserver : public test::EndToEndTest { + public: + NackObserver() + : EndToEndTest(kLongTimeoutMs), + rtp_parser_(RtpHeaderParser::Create()), + sent_rtp_packets_(0), + packets_left_to_drop_(0), + nacks_left_(kNumberOfNacksToObserve) {} - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); + private: + virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { + RTPHeader header; + EXPECT_TRUE( + rtp_parser_->Parse(packet, static_cast(length), &header)); - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); + // Never drop retransmitted packets. + if (dropped_packets_.find(header.sequenceNumber) != + dropped_packets_.end()) { + retransmitted_packets_.insert(header.sequenceNumber); + if (nacks_left_ == 0 && + retransmitted_packets_.size() == dropped_packets_.size()) { + observation_complete_->Set(); + } + return SEND_PACKET; + } - CreateTestConfigs(); - int rtp_history_ms = 1000; - send_config_.rtp.nack.rtp_history_ms = rtp_history_ms; - receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms; + ++sent_rtp_packets_; - CreateStreams(); - CreateFrameGenerator(); - StartSending(); + // Enough NACKs received, stop dropping packets. + if (nacks_left_ == 0) + return SEND_PACKET; - // Wait() waits for an event triggered when NACKs have been received, NACKed - // packets retransmitted and frames rendered again. - EXPECT_EQ(kEventSignaled, observer.Wait()); + // Check if it's time for a new loss burst. + if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0) + packets_left_to_drop_ = kLossBurstSize; - StopSending(); + if (packets_left_to_drop_ > 0) { + --packets_left_to_drop_; + dropped_packets_.insert(header.sequenceNumber); + return DROP_PACKET; + } - observer.StopSending(); + return SEND_PACKET; + } - DestroyStreams(); + virtual Action OnReceiveRtcp(const uint8_t* packet, + size_t length) OVERRIDE { + RTCPUtility::RTCPParserV2 parser(packet, length, true); + EXPECT_TRUE(parser.IsValid()); + + RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); + while (packet_type != RTCPUtility::kRtcpNotValidCode) { + if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) { + --nacks_left_; + break; + } + packet_type = parser.Iterate(); + } + return SEND_PACKET; + } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out waiting for packets to be NACKed, retransmitted and " + "rendered."; + } + + scoped_ptr rtp_parser_; + std::set dropped_packets_; + std::set retransmitted_packets_; + uint64_t sent_rtp_packets_; + int packets_left_to_drop_; + int nacks_left_; + } test; + + RunBaseTest(&test); } // TODO(pbos): Flaky, webrtc:3269 -TEST_F(CallTest, DISABLED_CanReceiveFec) { - class FecRenderObserver : public test::RtpRtcpObserver, public VideoRenderer { +TEST_F(EndToEndTest, DISABLED_CanReceiveFec) { + class FecRenderObserver : public test::EndToEndTest, public VideoRenderer { public: FecRenderObserver() - : RtpRtcpObserver(kDefaultTimeoutMs), + : EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket), protected_sequence_number_(0), protected_frame_timestamp_(0) {} @@ -457,10 +370,10 @@ TEST_F(CallTest, DISABLED_CanReceiveFec) { EXPECT_EQ(kRedPayloadType, header.payloadType); int encapsulated_payload_type = static_cast(packet[header.headerLength]); - if (encapsulated_payload_type != kSendPayloadType) + if (encapsulated_payload_type != kFakeSendPayloadType) EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); - switch(state_) { + switch (state_) { case kFirstPacket: state_ = kDropEveryOtherPacketUntilFec; break; @@ -473,7 +386,7 @@ TEST_F(CallTest, DISABLED_CanReceiveFec) { return DROP_PACKET; break; case kDropNextMediaPacket: - if (encapsulated_payload_type == kSendPayloadType) { + if (encapsulated_payload_type == kFakeSendPayloadType) { protected_sequence_number_ = header.sequenceNumber; protected_frame_timestamp_ = header.timestamp; state_ = kProtectedPacketDropped; @@ -507,54 +420,47 @@ TEST_F(CallTest, DISABLED_CanReceiveFec) { kProtectedPacketDropped, } state_; + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + // TODO(pbos): Run this test with combined NACK/FEC enabled as well. + // int rtp_history_ms = 1000; + // receive_config->rtp.nack.rtp_history_ms = rtp_history_ms; + // send_config->rtp.nack.rtp_history_ms = rtp_history_ms; + send_config->rtp.fec.red_payload_type = kRedPayloadType; + send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; + + receive_config->rtp.fec.red_payload_type = kRedPayloadType; + receive_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; + receive_config->renderer = this; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for retransmitted NACKed frames to be " + "rendered again."; + } + uint32_t protected_sequence_number_ GUARDED_BY(crit_); uint32_t protected_frame_timestamp_ GUARDED_BY(crit_); - } observer; + } test; - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); - - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - - CreateTestConfigs(); - // TODO(pbos): Run this test with combined NACK/FEC enabled as well. - // int rtp_history_ms = 1000; - // receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms; - // send_config_.rtp.nack.rtp_history_ms = rtp_history_ms; - send_config_.rtp.fec.red_payload_type = kRedPayloadType; - send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; - - receive_config_.rtp.fec.red_payload_type = kRedPayloadType; - receive_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; - receive_config_.renderer = &observer; - - CreateStreams(); - CreateFrameGenerator(); - StartSending(); - - // Wait() waits for an event triggered when NACKs have been received, NACKed - // packets retransmitted and frames rendered again. - EXPECT_EQ(kEventSignaled, observer.Wait()); - - StopSending(); - - observer.StopSending(); - - DestroyStreams(); + RunBaseTest(&test); } // This test drops second RTP packet with a marker bit set, makes sure it's // retransmitted and renders. Retransmission SSRCs are also checked. -void CallTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) { +void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) { static const int kDroppedFrameNumber = 2; - class RetransmissionObserver : public test::RtpRtcpObserver, + class RetransmissionObserver : public test::EndToEndTest, public I420FrameCallback { public: - RetransmissionObserver(bool expect_rtx) - : RtpRtcpObserver(kDefaultTimeoutMs), - retransmission_ssrc_(expect_rtx ? kSendRtxSsrc : kSendSsrc), + explicit RetransmissionObserver(bool expect_rtx) + : EndToEndTest(kDefaultTimeoutMs), + retransmission_ssrc_(expect_rtx ? kSendRtxSsrc : kSendSsrcs[0]), retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType - : kSendPayloadType), + : kFakeSendPayloadType), marker_bits_observed_(0), retransmitted_timestamp_(0), frame_retransmitted_(false) {} @@ -571,8 +477,8 @@ void CallTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) { return SEND_PACKET; } - EXPECT_EQ(kSendSsrc, header.ssrc); - EXPECT_EQ(kSendPayloadType, header.payloadType); + EXPECT_EQ(kSendSsrcs[0], header.ssrc); + EXPECT_EQ(kFakeSendPayloadType, header.payloadType); // Found the second frame's final packet, drop this and expect a // retransmission. @@ -592,51 +498,46 @@ void CallTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) { } } + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + receive_config->pre_render_callback = this; + receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + if (retransmission_ssrc_ == kSendRtxSsrc) { + send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrc); + send_config->rtp.rtx.payload_type = kSendRtxPayloadType; + receive_config->rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrc; + receive_config->rtp.rtx[kSendRtxPayloadType].payload_type = + kSendRtxPayloadType; + } + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for retransmission to render."; + } + const uint32_t retransmission_ssrc_; const int retransmission_payload_type_; int marker_bits_observed_; uint32_t retransmitted_timestamp_; bool frame_retransmitted_; - } observer(retransmit_over_rtx); + } test(retransmit_over_rtx); - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); - - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - - CreateTestConfigs(); - send_config_.rtp.nack.rtp_history_ms = - receive_config_.rtp.nack.rtp_history_ms = 1000; - if (retransmit_over_rtx) { - send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrc); - send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; - int payload_type = send_config_.encoder_settings.payload_type; - receive_config_.rtp.rtx[payload_type].ssrc = kSendRtxSsrc; - receive_config_.rtp.rtx[payload_type].payload_type = kSendRtxPayloadType; - } - receive_config_.pre_render_callback = &observer; - - CreateStreams(); - CreateFrameGenerator(); - StartSending(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while waiting for retransmission to render."; - - StopSending(); - observer.StopSending(); - DestroyStreams(); + RunBaseTest(&test); } -TEST_F(CallTest, DecodesRetransmittedFrame) { +TEST_F(EndToEndTest, DecodesRetransmittedFrame) { DecodesRetransmittedFrame(false); } -TEST_F(CallTest, DecodesRetransmittedFrameOverRtx) { +TEST_F(EndToEndTest, DecodesRetransmittedFrameOverRtx) { DecodesRetransmittedFrame(true); } -TEST_F(CallTest, UsesFrameCallbacks) { +TEST_F(EndToEndTest, UsesFrameCallbacks) { static const int kWidth = 320; static const int kHeight = 240; @@ -700,7 +601,7 @@ TEST_F(CallTest, UsesFrameCallbacks) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateTestConfigs(); + CreateSendConfig(1); scoped_ptr encoder(VP8Encoder::Create()); send_config_.encoder_settings.encoder = encoder.get(); send_config_.encoder_settings.payload_name = "VP8"; @@ -708,11 +609,8 @@ TEST_F(CallTest, UsesFrameCallbacks) { video_streams_[0].width = kWidth; video_streams_[0].height = kHeight; send_config_.pre_encode_callback = &pre_encode_callback; - receive_config_.codecs.clear(); - VideoCodec codec = - test::CreateDecoderVideoCodec(send_config_.encoder_settings); - receive_config_.external_decoders.clear(); - receive_config_.codecs.push_back(codec); + + CreateMatchingReceiveConfigs(); receive_config_.pre_render_callback = &pre_render_callback; receive_config_.renderer = &renderer; @@ -740,109 +638,102 @@ TEST_F(CallTest, UsesFrameCallbacks) { DestroyStreams(); } -class PliObserver : public test::RtpRtcpObserver, public VideoRenderer { - static const int kInverseDropProbability = 16; - - public: - explicit PliObserver(bool nack_enabled) - : test::RtpRtcpObserver(kLongTimeoutMs), - nack_enabled_(nack_enabled), - highest_dropped_timestamp_(0), - frames_to_drop_(0), - received_pli_(false) {} - - virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { - RTPHeader header; - EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); - - // Drop all retransmitted packets to force a PLI. - if (header.timestamp <= highest_dropped_timestamp_) - return DROP_PACKET; - - if (frames_to_drop_ > 0) { - highest_dropped_timestamp_ = header.timestamp; - --frames_to_drop_; - return DROP_PACKET; - } - - return SEND_PACKET; - } - - virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { - RTCPUtility::RTCPParserV2 parser(packet, length, true); - EXPECT_TRUE(parser.IsValid()); - - for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - packet_type != RTCPUtility::kRtcpNotValidCode; - packet_type = parser.Iterate()) { - if (!nack_enabled_) - EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode); - - if (packet_type == RTCPUtility::kRtcpPsfbPliCode) { - received_pli_ = true; - break; - } - } - return SEND_PACKET; - } - - virtual void RenderFrame(const I420VideoFrame& video_frame, - int time_to_render_ms) OVERRIDE { - CriticalSectionScoped lock(crit_.get()); - if (received_pli_ && video_frame.timestamp() > highest_dropped_timestamp_) { - observation_complete_->Set(); - } - if (!received_pli_) - frames_to_drop_ = kPacketsToDrop; - } - - private: +void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) { static const int kPacketsToDrop = 1; - bool nack_enabled_; - uint32_t highest_dropped_timestamp_; - int frames_to_drop_; - bool received_pli_; -}; + class PliObserver : public test::EndToEndTest, public VideoRenderer { + public: + explicit PliObserver(int rtp_history_ms) + : EndToEndTest(kLongTimeoutMs), + rtp_history_ms_(rtp_history_ms), + nack_enabled_(rtp_history_ms > 0), + highest_dropped_timestamp_(0), + frames_to_drop_(0), + received_pli_(false) {} -void CallTest::ReceivesPliAndRecovers(int rtp_history_ms) { - PliObserver observer(rtp_history_ms > 0); + private: + virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { + RTPHeader header; + EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); + // Drop all retransmitted packets to force a PLI. + if (header.timestamp <= highest_dropped_timestamp_) + return DROP_PACKET; - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); + if (frames_to_drop_ > 0) { + highest_dropped_timestamp_ = header.timestamp; + --frames_to_drop_; + return DROP_PACKET; + } - CreateTestConfigs(); - send_config_.rtp.nack.rtp_history_ms = rtp_history_ms; - receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms; - receive_config_.renderer = &observer; + return SEND_PACKET; + } - CreateStreams(); - CreateFrameGenerator(); - StartSending(); + virtual Action OnReceiveRtcp(const uint8_t* packet, + size_t length) OVERRIDE { + RTCPUtility::RTCPParserV2 parser(packet, length, true); + EXPECT_TRUE(parser.IsValid()); - // Wait() waits for an event triggered when Pli has been received and frames - // have been rendered afterwards. - EXPECT_EQ(kEventSignaled, observer.Wait()); + for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); + packet_type != RTCPUtility::kRtcpNotValidCode; + packet_type = parser.Iterate()) { + if (!nack_enabled_) + EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode); - StopSending(); + if (packet_type == RTCPUtility::kRtcpPsfbPliCode) { + received_pli_ = true; + break; + } + } + return SEND_PACKET; + } - observer.StopSending(); + virtual void RenderFrame(const I420VideoFrame& video_frame, + int time_to_render_ms) OVERRIDE { + CriticalSectionScoped lock(crit_.get()); + if (received_pli_ && + video_frame.timestamp() > highest_dropped_timestamp_) { + observation_complete_->Set(); + } + if (!received_pli_) + frames_to_drop_ = kPacketsToDrop; + } - DestroyStreams(); + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.nack.rtp_history_ms = rtp_history_ms_; + receive_config->rtp.nack.rtp_history_ms = rtp_history_ms_; + receive_config->renderer = this; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) << "Timed out waiting for PLI to be " + "received and a frame to be " + "rendered afterwards."; + } + + int rtp_history_ms_; + bool nack_enabled_; + uint32_t highest_dropped_timestamp_; + int frames_to_drop_; + bool received_pli_; + } test(rtp_history_ms); + + RunBaseTest(&test); } -TEST_F(CallTest, ReceivesPliAndRecoversWithNack) { +TEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) { ReceivesPliAndRecovers(1000); } // TODO(pbos): Enable this when 2250 is resolved. -TEST_F(CallTest, DISABLED_ReceivesPliAndRecoversWithoutNack) { +TEST_F(EndToEndTest, DISABLED_ReceivesPliAndRecoversWithoutNack) { ReceivesPliAndRecovers(0); } -TEST_F(CallTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { +TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { class PacketInputObserver : public PacketReceiver { public: explicit PacketInputObserver(PacketReceiver* receiver) @@ -878,7 +769,8 @@ TEST_F(CallTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { send_transport.SetReceiver(&input_observer); receive_transport.SetReceiver(sender_call_->Receiver()); - CreateTestConfigs(); + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); CreateStreams(); CreateFrameGenerator(); @@ -898,13 +790,12 @@ TEST_F(CallTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { receive_transport.StopSending(); } -void CallTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) { - static const int kRtpHistoryMs = 1000; +void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) { static const int kNumCompoundRtcpPacketsToObserve = 10; - class RtcpModeObserver : public test::RtpRtcpObserver { + class RtcpModeObserver : public test::EndToEndTest { public: explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode) - : test::RtpRtcpObserver(kDefaultTimeoutMs), + : EndToEndTest(kDefaultTimeoutMs), rtcp_mode_(rtcp_mode), sent_rtp_(0), sent_rtcp_(0) {} @@ -955,40 +846,35 @@ void CallTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) { return SEND_PACKET; } + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + receive_config->rtp.rtcp_mode = rtcp_mode_; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << (rtcp_mode_ == newapi::kRtcpCompound + ? "Timed out before observing enough compound packets." + : "Timed out before receiving a non-compound RTCP packet."); + } + newapi::RtcpMode rtcp_mode_; int sent_rtp_; int sent_rtcp_; - } observer(rtcp_mode); + } test(rtcp_mode); - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); - - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - - CreateTestConfigs(); - send_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs; - receive_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs; - receive_config_.rtp.rtcp_mode = rtcp_mode; - - CreateStreams(); - CreateFrameGenerator(); - StartSending(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << (rtcp_mode == newapi::kRtcpCompound - ? "Timed out before observing enough compound packets." - : "Timed out before receiving a non-compound RTCP packet."); - - StopSending(); - observer.StopSending(); - DestroyStreams(); + RunBaseTest(&test); } -TEST_F(CallTest, UsesRtcpCompoundMode) { +TEST_F(EndToEndTest, UsesRtcpCompoundMode) { RespectsRtcpMode(newapi::kRtcpCompound); } -TEST_F(CallTest, UsesRtcpReducedSizeMode) { +TEST_F(EndToEndTest, UsesRtcpReducedSizeMode) { RespectsRtcpMode(newapi::kRtcpReducedSize); } @@ -996,7 +882,7 @@ TEST_F(CallTest, UsesRtcpReducedSizeMode) { // Another is set up to receive all three of these with different renderers. // Each renderer verifies that it receives the expected resolution, and as soon // as every renderer has received a frame, the test finishes. -TEST_F(CallTest, SendsAndReceivesMultipleStreams) { +TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) { static const size_t kNumStreams = 3; class VideoOutputObserver : public VideoRenderer { @@ -1103,9 +989,9 @@ TEST_F(CallTest, SendsAndReceivesMultipleStreams) { sender_transport.StopSending(); receiver_transport.StopSending(); -}; +} -TEST_F(CallTest, ObserversEncodedFrames) { +TEST_F(EndToEndTest, ObserversEncodedFrames) { class EncodedFrameTestObserver : public EncodedFrameObserver { public: EncodedFrameTestObserver() @@ -1151,7 +1037,8 @@ TEST_F(CallTest, ObserversEncodedFrames) { sender_transport.SetReceiver(receiver_call_->Receiver()); receiver_transport.SetReceiver(sender_call_->Receiver()); - CreateTestConfigs(); + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); send_config_.post_encode_callback = &post_encode_observer; receive_config_.pre_decode_callback = &pre_decode_observer; @@ -1178,10 +1065,10 @@ TEST_F(CallTest, ObserversEncodedFrames) { DestroyStreams(); } -TEST_F(CallTest, ReceiveStreamSendsRemb) { - class RembObserver : public test::RtpRtcpObserver { +TEST_F(EndToEndTest, ReceiveStreamSendsRemb) { + class RembObserver : public test::EndToEndTest { public: - RembObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {} + RembObserver() : EndToEndTest(kDefaultTimeoutMs) {} virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { @@ -1200,7 +1087,7 @@ TEST_F(CallTest, ReceiveStreamSendsRemb) { const RTCPUtility::RTCPPacket& packet = parser.Packet(); EXPECT_GT(packet.REMBItem.BitRate, 0u); EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u); - EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrc); + EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrcs[0]); received_remb = true; } packet_type = parser.Iterate(); @@ -1209,30 +1096,22 @@ TEST_F(CallTest, ReceiveStreamSendsRemb) { observation_complete_->Set(); return SEND_PACKET; } - } observer; + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for a " + "receiver RTCP REMB packet to be " + "sent."; + } + } test; - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - CreateTestConfigs(); - CreateStreams(); - CreateFrameGenerator(); - StartSending(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while waiting for a receiver RTCP REMB packet to be sent."; - - StopSending(); - observer.StopSending(); - DestroyStreams(); + RunBaseTest(&test); } -void CallTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { +void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { static const int kNumRtcpReportPacketsToObserve = 5; - class RtcpXrObserver : public test::RtpRtcpObserver { + class RtcpXrObserver : public test::EndToEndTest { public: explicit RtcpXrObserver(bool enable_rrtr) - : test::RtpRtcpObserver(kDefaultTimeoutMs), + : EndToEndTest(kDefaultTimeoutMs), enable_rrtr_(enable_rrtr), sent_rtcp_sr_(0), sent_rtcp_rr_(0), @@ -1288,293 +1167,271 @@ void CallTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { } return SEND_PACKET; } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + receive_config->rtp.rtcp_mode = newapi::kRtcpReducedSize; + receive_config->rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr_; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for RTCP SR/RR packets to be sent."; + } + bool enable_rrtr_; int sent_rtcp_sr_; int sent_rtcp_rr_; int sent_rtcp_rrtr_; int sent_rtcp_dlrr_; - } observer(enable_rrtr); + } test(enable_rrtr); - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - - CreateTestConfigs(); - receive_config_.rtp.rtcp_mode = newapi::kRtcpReducedSize; - receive_config_.rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr; - - CreateStreams(); - CreateFrameGenerator(); - StartSending(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while waiting for RTCP SR/RR packets to be sent."; - - StopSending(); - observer.StopSending(); - DestroyStreams(); + RunBaseTest(&test); } -class StatsObserver : public test::RtpRtcpObserver, public I420FrameCallback { - public: - StatsObserver() - : test::RtpRtcpObserver(kLongTimeoutMs), - receive_stream_(NULL), - send_stream_(NULL), - expected_receive_ssrc_(), - expected_send_ssrcs_(), - check_stats_event_(EventWrapper::Create()) {} +TEST_F(EndToEndTest, GetStats) { + class StatsObserver : public test::EndToEndTest, public I420FrameCallback { + public: + StatsObserver() + : EndToEndTest(kLongTimeoutMs), + receive_stream_(NULL), + send_stream_(NULL), + expected_receive_ssrc_(), + expected_send_ssrcs_(), + check_stats_event_(EventWrapper::Create()) {} - void SetExpectedReceiveSsrc(uint32_t ssrc) { expected_receive_ssrc_ = ssrc; } - - void SetExpectedSendSsrcs(const std::vector& ssrcs) { - for (std::vector::const_iterator it = ssrcs.begin(); - it != ssrcs.end(); - ++it) { - expected_send_ssrcs_.insert(*it); - } - } - - void SetExpectedCName(std::string cname) { expected_cname_ = cname; } - - void SetReceiveStream(VideoReceiveStream* stream) { - receive_stream_ = stream; - } - - void SetSendStream(VideoSendStream* stream) { send_stream_ = stream; } - - void WaitForFilledStats() { - Clock* clock = Clock::GetRealTimeClock(); - int64_t now = clock->TimeInMilliseconds(); - int64_t stop_time = now + kLongTimeoutMs; - bool receive_ok = false; - bool send_ok = false; - - while (now < stop_time) { - if (!receive_ok) - receive_ok = CheckReceiveStats(); - if (!send_ok) - send_ok = CheckSendStats(); - - if (receive_ok && send_ok) - return; - - int64_t time_until_timout_ = stop_time - now; - if (time_until_timout_ > 0) - check_stats_event_->Wait(time_until_timout_); - now = clock->TimeInMilliseconds(); + private: + virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { + check_stats_event_->Set(); + return SEND_PACKET; } - ADD_FAILURE() << "Timed out waiting for filled stats."; - for (std::map::const_iterator it = - receive_stats_filled_.begin(); - it != receive_stats_filled_.end(); - ++it) { - if (!it->second) { - ADD_FAILURE() << "Missing receive stats: " << it->first; + virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { + check_stats_event_->Set(); + return SEND_PACKET; + } + + virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE { + check_stats_event_->Set(); + return SEND_PACKET; + } + + virtual Action OnReceiveRtcp(const uint8_t* packet, + size_t length) OVERRIDE { + check_stats_event_->Set(); + return SEND_PACKET; + } + + virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE { + // Ensure that we have at least 5ms send side delay. + int64_t render_time = video_frame->render_time_ms(); + if (render_time > 0) + video_frame->set_render_time_ms(render_time - 5); + } + + bool CheckReceiveStats() { + assert(receive_stream_ != NULL); + VideoReceiveStream::Stats stats = receive_stream_->GetStats(); + EXPECT_EQ(expected_receive_ssrc_, stats.ssrc); + + // Make sure all fields have been populated. + + receive_stats_filled_["IncomingRate"] |= + stats.network_frame_rate != 0 || stats.bitrate_bps != 0; + + receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0; + + receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0; + + receive_stats_filled_["StatisticsUpdated"] |= + stats.rtcp_stats.cumulative_lost != 0 || + stats.rtcp_stats.extended_max_sequence_number != 0 || + stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0; + + receive_stats_filled_["DataCountersUpdated"] |= + stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 || + stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 || + stats.rtp_stats.padding_bytes != 0 || + stats.rtp_stats.retransmitted_packets != 0; + + receive_stats_filled_["CodecStats"] |= + stats.avg_delay_ms != 0 || stats.discarded_packets != 0 || + stats.key_frames != 0 || stats.delta_frames != 0; + + receive_stats_filled_["CName"] |= stats.c_name == expected_cname_; + + return AllStatsFilled(receive_stats_filled_); + } + + bool CheckSendStats() { + assert(send_stream_ != NULL); + VideoSendStream::Stats stats = send_stream_->GetStats(); + + send_stats_filled_["NumStreams"] |= + stats.substreams.size() == expected_send_ssrcs_.size(); + + send_stats_filled_["Delay"] |= + stats.avg_delay_ms != 0 || stats.max_delay_ms != 0; + + receive_stats_filled_["CName"] |= stats.c_name == expected_cname_; + + for (std::map::const_iterator it = + stats.substreams.begin(); + it != stats.substreams.end(); + ++it) { + EXPECT_TRUE(expected_send_ssrcs_.find(it->first) != + expected_send_ssrcs_.end()); + + send_stats_filled_[CompoundKey("IncomingRate", it->first)] |= + stats.input_frame_rate != 0; + + const StreamStats& stream_stats = it->second; + + send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |= + stream_stats.rtcp_stats.cumulative_lost != 0 || + stream_stats.rtcp_stats.extended_max_sequence_number != 0 || + stream_stats.rtcp_stats.fraction_lost != 0; + + send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |= + stream_stats.rtp_stats.fec_packets != 0 || + stream_stats.rtp_stats.padding_bytes != 0 || + stream_stats.rtp_stats.retransmitted_packets != 0 || + stream_stats.rtp_stats.packets != 0; + + send_stats_filled_[CompoundKey("BitrateStatisticsObserver", + it->first)] |= + stream_stats.bitrate_bps != 0; + + send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |= + stream_stats.delta_frames != 0 || stream_stats.key_frames != 0; + + send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |= + stats.encode_frame_rate != 0; + } + + return AllStatsFilled(send_stats_filled_); + } + + std::string CompoundKey(const char* name, uint32_t ssrc) { + std::ostringstream oss; + oss << name << "_" << ssrc; + return oss.str(); + } + + bool AllStatsFilled(const std::map& stats_map) { + for (std::map::const_iterator it = stats_map.begin(); + it != stats_map.end(); + ++it) { + if (!it->second) + return false; + } + return true; + } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->pre_encode_callback = this; // Used to inject delay. + send_config->rtp.c_name = "SomeCName"; + + expected_receive_ssrc_ = receive_config->rtp.local_ssrc; + const std::vector& ssrcs = send_config->rtp.ssrcs; + for (size_t i = 0; i < ssrcs.size(); ++i) + expected_send_ssrcs_.insert(ssrcs[i]); + + expected_cname_ = send_config->rtp.c_name; + } + + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) OVERRIDE { + send_stream_ = send_stream; + receive_stream_ = receive_stream; + } + + virtual void PerformTest() OVERRIDE { + Clock* clock = Clock::GetRealTimeClock(); + int64_t now = clock->TimeInMilliseconds(); + int64_t stop_time = now + test::CallTest::kLongTimeoutMs; + bool receive_ok = false; + bool send_ok = false; + + while (now < stop_time) { + if (!receive_ok) + receive_ok = CheckReceiveStats(); + if (!send_ok) + send_ok = CheckSendStats(); + + if (receive_ok && send_ok) + return; + + int64_t time_until_timout_ = stop_time - now; + if (time_until_timout_ > 0) + check_stats_event_->Wait(time_until_timout_); + now = clock->TimeInMilliseconds(); + } + + ADD_FAILURE() << "Timed out waiting for filled stats."; + for (std::map::const_iterator it = + receive_stats_filled_.begin(); + it != receive_stats_filled_.end(); + ++it) { + if (!it->second) { + ADD_FAILURE() << "Missing receive stats: " << it->first; + } + } + + for (std::map::const_iterator it = + send_stats_filled_.begin(); + it != send_stats_filled_.end(); + ++it) { + if (!it->second) { + ADD_FAILURE() << "Missing send stats: " << it->first; + } } } - for (std::map::const_iterator it = - send_stats_filled_.begin(); - it != send_stats_filled_.end(); - ++it) { - if (!it->second) { - ADD_FAILURE() << "Missing send stats: " << it->first; - } - } - } + VideoReceiveStream* receive_stream_; + std::map receive_stats_filled_; - private: - virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { - check_stats_event_->Set(); - return SEND_PACKET; - } + VideoSendStream* send_stream_; + std::map send_stats_filled_; - virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { - check_stats_event_->Set(); - return SEND_PACKET; - } + uint32_t expected_receive_ssrc_; + std::set expected_send_ssrcs_; + std::string expected_cname_; - virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE { - check_stats_event_->Set(); - return SEND_PACKET; - } + scoped_ptr check_stats_event_; + } test; - virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { - check_stats_event_->Set(); - return SEND_PACKET; - } - - virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE { - // Ensure that we have at least 5ms send side delay. - int64_t render_time = video_frame->render_time_ms(); - if (render_time > 0) - video_frame->set_render_time_ms(render_time - 5); - } - - bool CheckReceiveStats() { - assert(receive_stream_ != NULL); - VideoReceiveStream::Stats stats = receive_stream_->GetStats(); - EXPECT_EQ(expected_receive_ssrc_, stats.ssrc); - - // Make sure all fields have been populated. - - receive_stats_filled_["IncomingRate"] |= - stats.network_frame_rate != 0 || stats.bitrate_bps != 0; - - receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0; - - receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0; - - receive_stats_filled_["StatisticsUpdated"] |= - stats.rtcp_stats.cumulative_lost != 0 || - stats.rtcp_stats.extended_max_sequence_number != 0 || - stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0; - - receive_stats_filled_["DataCountersUpdated"] |= - stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 || - stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 || - stats.rtp_stats.padding_bytes != 0 || - stats.rtp_stats.retransmitted_packets != 0; - - receive_stats_filled_["CodecStats"] |= - stats.avg_delay_ms != 0 || stats.discarded_packets != 0 || - stats.key_frames != 0 || stats.delta_frames != 0; - - receive_stats_filled_["CName"] |= stats.c_name == expected_cname_; - - return AllStatsFilled(receive_stats_filled_); - } - - bool CheckSendStats() { - assert(send_stream_ != NULL); - VideoSendStream::Stats stats = send_stream_->GetStats(); - - send_stats_filled_["NumStreams"] |= - stats.substreams.size() == expected_send_ssrcs_.size(); - - send_stats_filled_["Delay"] |= - stats.avg_delay_ms != 0 || stats.max_delay_ms != 0; - - receive_stats_filled_["CName"] |= stats.c_name == expected_cname_; - - for (std::map::const_iterator it = - stats.substreams.begin(); - it != stats.substreams.end(); - ++it) { - EXPECT_TRUE(expected_send_ssrcs_.find(it->first) != - expected_send_ssrcs_.end()); - - send_stats_filled_[CompoundKey("IncomingRate", it->first)] |= - stats.input_frame_rate != 0; - - const StreamStats& stream_stats = it->second; - - send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |= - stream_stats.rtcp_stats.cumulative_lost != 0 || - stream_stats.rtcp_stats.extended_max_sequence_number != 0 || - stream_stats.rtcp_stats.fraction_lost != 0; - - send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |= - stream_stats.rtp_stats.fec_packets != 0 || - stream_stats.rtp_stats.padding_bytes != 0 || - stream_stats.rtp_stats.retransmitted_packets != 0 || - stream_stats.rtp_stats.packets != 0; - - send_stats_filled_[CompoundKey("BitrateStatisticsObserver", it->first)] |= - stream_stats.bitrate_bps != 0; - - send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |= - stream_stats.delta_frames != 0 || stream_stats.key_frames != 0; - - send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |= - stats.encode_frame_rate != 0; - } - - return AllStatsFilled(send_stats_filled_); - } - - std::string CompoundKey(const char* name, uint32_t ssrc) { - std::ostringstream oss; - oss << name << "_" << ssrc; - return oss.str(); - } - - bool AllStatsFilled(const std::map& stats_map) { - for (std::map::const_iterator it = stats_map.begin(); - it != stats_map.end(); - ++it) { - if (!it->second) - return false; - } - return true; - } - - VideoReceiveStream* receive_stream_; - std::map receive_stats_filled_; - - VideoSendStream* send_stream_; - std::map send_stats_filled_; - - uint32_t expected_receive_ssrc_; - std::set expected_send_ssrcs_; - std::string expected_cname_; - - scoped_ptr check_stats_event_; -}; - -TEST_F(CallTest, GetStats) { - StatsObserver observer; - - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); - - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - - CreateTestConfigs(); - send_config_.pre_encode_callback = &observer; // Used to inject delay. - send_config_.rtp.c_name = "SomeCName"; - - observer.SetExpectedReceiveSsrc(receive_config_.rtp.local_ssrc); - observer.SetExpectedSendSsrcs(send_config_.rtp.ssrcs); - observer.SetExpectedCName(send_config_.rtp.c_name); - - CreateStreams(); - observer.SetReceiveStream(receive_stream_); - observer.SetSendStream(send_stream_); - CreateFrameGenerator(); - StartSending(); - - observer.WaitForFilledStats(); - - StopSending(); - observer.StopSending(); - DestroyStreams(); + RunBaseTest(&test); } -TEST_F(CallTest, ReceiverReferenceTimeReportEnabled) { +TEST_F(EndToEndTest, ReceiverReferenceTimeReportEnabled) { TestXrReceiverReferenceTimeReport(true); } -TEST_F(CallTest, ReceiverReferenceTimeReportDisabled) { +TEST_F(EndToEndTest, ReceiverReferenceTimeReportDisabled) { TestXrReceiverReferenceTimeReport(false); } -TEST_F(CallTest, TestReceivedRtpPacketStats) { +TEST_F(EndToEndTest, TestReceivedRtpPacketStats) { static const size_t kNumRtpPacketsToSend = 5; - class ReceivedRtpStatsObserver : public test::RtpRtcpObserver { + class ReceivedRtpStatsObserver : public test::EndToEndTest { public: ReceivedRtpStatsObserver() - : test::RtpRtcpObserver(kDefaultTimeoutMs), + : EndToEndTest(kDefaultTimeoutMs), receive_stream_(NULL), sent_rtp_(0) {} - void SetReceiveStream(VideoReceiveStream* stream) { - receive_stream_ = stream; + private: + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) OVERRIDE { + receive_stream_ = receive_stream; } - private: virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { if (sent_rtp_ >= kNumRtpPacketsToSend) { VideoReceiveStream::Stats stats = receive_stream_->GetStats(); @@ -1587,26 +1444,16 @@ TEST_F(CallTest, TestReceivedRtpPacketStats) { return SEND_PACKET; } + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while verifying number of received RTP packets."; + } + VideoReceiveStream* receive_stream_; uint32_t sent_rtp_; - } observer; + } test; - CreateCalls(Call::Config(observer.SendTransport()), - Call::Config(observer.ReceiveTransport())); - observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); - - CreateTestConfigs(); - CreateStreams(); - observer.SetReceiveStream(receive_stream_); - CreateFrameGenerator(); - StartSending(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while verifying number of received RTP packets."; - - StopSending(); - observer.StopSending(); - DestroyStreams(); + RunBaseTest(&test); } } // namespace webrtc diff --git a/webrtc/video/full_stack.cc b/webrtc/video/full_stack.cc index 6b21cbe12..1c03042db 100644 --- a/webrtc/video/full_stack.cc +++ b/webrtc/video/full_stack.cc @@ -24,6 +24,7 @@ #include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/system_wrappers/interface/sleep.h" #include "webrtc/system_wrappers/interface/thread_annotations.h" +#include "webrtc/test/call_test.h" #include "webrtc/test/direct_transport.h" #include "webrtc/test/encoder_settings.h" #include "webrtc/test/fake_encoder.h" @@ -34,7 +35,6 @@ namespace webrtc { -static const uint32_t kSendSsrc = 0x654321; static const int kFullStackTestDurationSecs = 10; struct FullStackTestParams { @@ -49,20 +49,9 @@ struct FullStackTestParams { double avg_ssim_threshold; }; -FullStackTestParams paris_qcif = { - "net_delay_0_0_plr_0", {"paris_qcif", 176, 144, 30}, 300, 36.0, 0.96}; - -// TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif. -FullStackTestParams foreman_cif = { - "foreman_cif_net_delay_0_0_plr_0", - {"foreman_cif", 352, 288, 30}, - 700, - 0.0, - 0.0}; - -class FullStackTest : public ::testing::TestWithParam { +class FullStackTest : public test::CallTest { protected: - std::map reserved_ssrcs_; + void TestWithoutPacketLoss(const FullStackTestParams& params); }; class VideoAnalyzer : public PacketReceiver, @@ -200,7 +189,9 @@ class VideoAnalyzer : public PacketReceiver, last_rendered_frame_.CopyFrame(video_frame); } - void Wait() { done_->Wait(120 * 1000); } + void Wait() { + EXPECT_EQ(kEventSignaled, done_->Wait(FullStackTest::kLongTimeoutMs)); + } VideoSendStreamInput* input_; Transport* transport_; @@ -376,10 +367,7 @@ class VideoAnalyzer : public PacketReceiver, const scoped_ptr done_; }; -TEST_P(FullStackTest, NoPacketLoss) { - static const uint32_t kReceiverLocalSsrc = 0x123456; - FullStackTestParams params = GetParam(); - +void FullStackTest::TestWithoutPacketLoss(const FullStackTestParams& params) { test::DirectTransport transport; VideoAnalyzer analyzer(NULL, &transport, @@ -388,32 +376,32 @@ TEST_P(FullStackTest, NoPacketLoss) { params.avg_ssim_threshold, kFullStackTestDurationSecs * params.clip.fps); - Call::Config call_config(&analyzer); + CreateCalls(Call::Config(&analyzer), Call::Config(&analyzer)); - scoped_ptr call(Call::Create(call_config)); - analyzer.SetReceiver(call->Receiver()); + analyzer.SetReceiver(receiver_call_->Receiver()); transport.SetReceiver(&analyzer); - VideoSendStream::Config send_config = call->GetDefaultSendConfig(); - send_config.rtp.ssrcs.push_back(kSendSsrc); + CreateSendConfig(1); scoped_ptr encoder(VP8Encoder::Create()); - send_config.encoder_settings.encoder = encoder.get(); - send_config.encoder_settings.payload_name = "VP8"; - send_config.encoder_settings.payload_type = 124; - std::vector video_streams = test::CreateVideoStreams(1); - VideoStream* stream = &video_streams[0]; + send_config_.encoder_settings.encoder = encoder.get(); + send_config_.encoder_settings.payload_name = "VP8"; + send_config_.encoder_settings.payload_type = 124; + + VideoStream* stream = &video_streams_[0]; stream->width = params.clip.width; stream->height = params.clip.height; stream->min_bitrate_bps = stream->target_bitrate_bps = stream->max_bitrate_bps = params.bitrate * 1000; stream->max_framerate = params.clip.fps; - VideoSendStream* send_stream = - call->CreateVideoSendStream(send_config, video_streams, NULL); - analyzer.input_ = send_stream->Input(); + CreateMatchingReceiveConfigs(); + receive_config_.renderer = &analyzer; - scoped_ptr file_capturer( + CreateStreams(); + analyzer.input_ = send_stream_->Input(); + + frame_generator_capturer_.reset( test::FrameGeneratorCapturer::CreateFromYuvFile( &analyzer, test::ResourcePath(params.clip.name, "yuv").c_str(), @@ -421,39 +409,41 @@ TEST_P(FullStackTest, NoPacketLoss) { params.clip.height, params.clip.fps, Clock::GetRealTimeClock())); - ASSERT_TRUE(file_capturer.get() != NULL) + + ASSERT_TRUE(frame_generator_capturer_.get() != NULL) << "Could not create capturer for " << params.clip.name << ".yuv. Is this resource file present?"; - VideoReceiveStream::Config receive_config = call->GetDefaultReceiveConfig(); - VideoCodec codec = - test::CreateDecoderVideoCodec(send_config.encoder_settings); - receive_config.codecs.push_back(codec); - receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0]; - receive_config.rtp.local_ssrc = kReceiverLocalSsrc; - receive_config.renderer = &analyzer; - - VideoReceiveStream* receive_stream = - call->CreateVideoReceiveStream(receive_config); - - receive_stream->Start(); - send_stream->Start(); - file_capturer->Start(); + Start(); analyzer.Wait(); - file_capturer->Stop(); - send_stream->Stop(); - receive_stream->Stop(); - - call->DestroyVideoReceiveStream(receive_stream); - call->DestroyVideoSendStream(send_stream); - transport.StopSending(); + + Stop(); + + DestroyStreams(); } -INSTANTIATE_TEST_CASE_P(FullStack, - FullStackTest, - ::testing::Values(paris_qcif, foreman_cif)); +FullStackTestParams paris_qcif = {"net_delay_0_0_plr_0", + {"paris_qcif", 176, 144, 30}, + 300, + 36.0, + 0.96}; + +// TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif. +FullStackTestParams foreman_cif = {"foreman_cif_net_delay_0_0_plr_0", + {"foreman_cif", 352, 288, 30}, + 700, + 0.0, + 0.0}; + +TEST_F(FullStackTest, ParisQcifWithoutPacketLoss) { + TestWithoutPacketLoss(paris_qcif); +} + +TEST_F(FullStackTest, ForemanCifWithoutPacketLoss) { + TestWithoutPacketLoss(foreman_cif); +} } // namespace webrtc diff --git a/webrtc/video/rampup_tests.cc b/webrtc/video/rampup_tests.cc index 94f1c19d9..5529f92ee 100644 --- a/webrtc/video/rampup_tests.cc +++ b/webrtc/video/rampup_tests.cc @@ -27,6 +27,7 @@ #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" #include "webrtc/system_wrappers/interface/event_wrapper.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/test/call_test.h" #include "webrtc/test/direct_transport.h" #include "webrtc/test/encoder_settings.h" #include "webrtc/test/fake_decoder.h" @@ -388,7 +389,9 @@ class LowRateStreamObserver : public test::DirectTransport, } } - EventTypeWrapper Wait() { return test_done_->Wait(120 * 1000); } + EventTypeWrapper Wait() { + return test_done_->Wait(test::CallTest::kLongTimeoutMs); + } private: static const unsigned int kHighBandwidthLimitBps = 80000; @@ -420,10 +423,7 @@ class LowRateStreamObserver : public test::DirectTransport, }; } // namespace -class RampUpTest : public ::testing::Test { - public: - virtual void SetUp() { reserved_ssrcs_.clear(); } - +class RampUpTest : public test::CallTest { protected: void RunRampUpTest(bool rtx, size_t num_streams, @@ -445,33 +445,26 @@ class RampUpTest : public ::testing::Test { call_config.start_bitrate_bps = start_bitrate_bps; stream_observer.set_start_bitrate_bps(start_bitrate_bps); } - scoped_ptr call(Call::Create(call_config)); - VideoSendStream::Config send_config = call->GetDefaultSendConfig(); - receiver_transport.SetReceiver(call->Receiver()); + CreateSenderCall(call_config); + CreateSendConfig(num_streams); - test::FakeEncoder encoder(Clock::GetRealTimeClock()); - send_config.encoder_settings.encoder = &encoder; - send_config.encoder_settings.payload_type = 125; - send_config.encoder_settings.payload_name = "FAKE"; - std::vector video_streams = - test::CreateVideoStreams(num_streams); + receiver_transport.SetReceiver(sender_call_->Receiver()); if (num_streams == 1) { - video_streams[0].target_bitrate_bps = 2000000; - video_streams[0].max_bitrate_bps = 2000000; + video_streams_[0].target_bitrate_bps = 2000000; + video_streams_[0].max_bitrate_bps = 2000000; } - send_config.rtp.nack.rtp_history_ms = 1000; - send_config.rtp.ssrcs = ssrcs; + send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config_.rtp.ssrcs = ssrcs; if (rtx) { - send_config.rtp.rtx.payload_type = 96; - send_config.rtp.rtx.ssrcs = rtx_ssrcs; - send_config.rtp.rtx.pad_with_redundant_payloads = true; + send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; + send_config_.rtp.rtx.ssrcs = rtx_ssrcs; + send_config_.rtp.rtx.pad_with_redundant_payloads = true; } - send_config.rtp.extensions.push_back( - RtpExtension(RtpExtension::kTOffset, - kTransmissionTimeOffsetExtensionId)); + send_config_.rtp.extensions.push_back(RtpExtension( + RtpExtension::kTOffset, kTransmissionTimeOffsetExtensionId)); if (num_streams == 1) { // For single stream rampup until 1mbps @@ -480,32 +473,22 @@ class RampUpTest : public ::testing::Test { // For multi stream rampup until all streams are being sent. That means // enough birate to send all the target streams plus the min bitrate of // the last one. - int expected_bitrate_bps = video_streams.back().min_bitrate_bps; - for (size_t i = 0; i < video_streams.size() - 1; ++i) { - expected_bitrate_bps += video_streams[i].target_bitrate_bps; + int expected_bitrate_bps = video_streams_.back().min_bitrate_bps; + for (size_t i = 0; i < video_streams_.size() - 1; ++i) { + expected_bitrate_bps += video_streams_[i].target_bitrate_bps; } stream_observer.set_expected_bitrate_bps(expected_bitrate_bps); } - VideoSendStream* send_stream = - call->CreateVideoSendStream(send_config, video_streams, NULL); + CreateStreams(); + CreateFrameGeneratorCapturer(); - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create(send_stream->Input(), - video_streams.back().width, - video_streams.back().height, - video_streams.back().max_framerate, - Clock::GetRealTimeClock())); - - send_stream->Start(); - frame_generator_capturer->Start(); + Start(); EXPECT_EQ(kEventSignaled, stream_observer.Wait()); - frame_generator_capturer->Stop(); - send_stream->Stop(); - - call->DestroyVideoSendStream(send_stream); + Stop(); + DestroyStreams(); } void RunRampUpDownUpTest(size_t number_of_streams, bool rtx) { @@ -520,59 +503,27 @@ class RampUpTest : public ::testing::Test { webrtc::Config webrtc_config; call_config.webrtc_config = &webrtc_config; webrtc_config.Set(new PaddingStrategy(rtx)); - scoped_ptr call(Call::Create(call_config)); - VideoSendStream::Config send_config = call->GetDefaultSendConfig(); + CreateSenderCall(call_config); + receiver_transport.SetReceiver(sender_call_->Receiver()); - receiver_transport.SetReceiver(call->Receiver()); + CreateSendConfig(number_of_streams); - test::FakeEncoder encoder(Clock::GetRealTimeClock()); - send_config.encoder_settings.encoder = &encoder; - send_config.encoder_settings.payload_type = 125; - send_config.encoder_settings.payload_name = "FAKE"; - std::vector video_streams = - test::CreateVideoStreams(number_of_streams); + send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config_.rtp.extensions.push_back(RtpExtension( + RtpExtension::kTOffset, kTransmissionTimeOffsetExtensionId)); + send_config_.suspend_below_min_bitrate = true; - send_config.rtp.nack.rtp_history_ms = 1000; - send_config.rtp.ssrcs.insert( - send_config.rtp.ssrcs.begin(), ssrcs.begin(), ssrcs.end()); - send_config.rtp.extensions.push_back( - RtpExtension(RtpExtension::kTOffset, - kTransmissionTimeOffsetExtensionId)); - send_config.suspend_below_min_bitrate = true; + CreateStreams(); + stream_observer.SetSendStream(send_stream_); - VideoSendStream* send_stream = - call->CreateVideoSendStream(send_config, video_streams, NULL); - stream_observer.SetSendStream(send_stream); + CreateFrameGeneratorCapturer(); - size_t width = 0; - size_t height = 0; - for (size_t i = 0; i < video_streams.size(); ++i) { - size_t stream_width = video_streams[i].width; - size_t stream_height = video_streams[i].height; - if (stream_width > width) - width = stream_width; - if (stream_height > height) - height = stream_height; - } - - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create(send_stream->Input(), - width, - height, - 30, - Clock::GetRealTimeClock())); - - send_stream->Start(); - frame_generator_capturer->Start(); + Start(); EXPECT_EQ(kEventSignaled, stream_observer.Wait()); - stream_observer.StopSending(); - receiver_transport.StopSending(); - frame_generator_capturer->Stop(); - send_stream->Stop(); - - call->DestroyVideoSendStream(send_stream); + Stop(); + DestroyStreams(); } private: @@ -583,8 +534,6 @@ class RampUpTest : public ::testing::Test { ssrcs.push_back(static_cast(ssrc_offset + i)); return ssrcs; } - - std::map reserved_ssrcs_; }; TEST_F(RampUpTest, SingleStream) { diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc index 3ae15d480..2d9bf5b5f 100644 --- a/webrtc/video/video_send_stream_tests.cc +++ b/webrtc/video/video_send_stream_tests.cc @@ -27,13 +27,9 @@ #include "webrtc/system_wrappers/interface/scoped_vector.h" #include "webrtc/system_wrappers/interface/sleep.h" #include "webrtc/system_wrappers/interface/thread_wrapper.h" -#include "webrtc/test/direct_transport.h" +#include "webrtc/test/call_test.h" #include "webrtc/test/configurable_frame_size_encoder.h" -#include "webrtc/test/encoder_settings.h" -#include "webrtc/test/fake_encoder.h" -#include "webrtc/test/frame_generator_capturer.h" #include "webrtc/test/null_transport.h" -#include "webrtc/test/rtp_rtcp_observer.h" #include "webrtc/test/testsupport/perf_test.h" #include "webrtc/video/transport_adapter.h" #include "webrtc/video_send_stream.h" @@ -59,94 +55,43 @@ class FakeNativeHandle : public NativeHandle { virtual void* GetHandle() { return NULL; } }; -class VideoSendStreamTest : public ::testing::Test { - public: - VideoSendStreamTest() - : send_stream_(NULL), fake_encoder_(Clock::GetRealTimeClock()) {} - +class VideoSendStreamTest : public test::CallTest { protected: - void RunSendTest(Call* call, - test::RtpRtcpObserver* observer) { - send_stream_ = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create( - send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); - send_stream_->Start(); - frame_generator_capturer->Start(); - - EXPECT_EQ(kEventSignaled, observer->Wait()); - - observer->StopSending(); - frame_generator_capturer->Stop(); - send_stream_->Stop(); - call->DestroyVideoSendStream(send_stream_); - } - - void CreateTestConfig(Call* call, size_t num_streams) { - assert(num_streams <= kNumSendSsrcs); - send_config_ = call->GetDefaultSendConfig(); - send_config_.encoder_settings.encoder = &fake_encoder_; - send_config_.encoder_settings.payload_name = "FAKE"; - send_config_.encoder_settings.payload_type = kFakeSendPayloadType; - video_streams_ = test::CreateVideoStreams(num_streams); - send_config_.encoder_settings.payload_type = kFakeSendPayloadType; - for (size_t i = 0; i < num_streams; ++i) - send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]); - } - void TestNackRetransmission(uint32_t retransmit_ssrc, uint8_t retransmit_payload_type); - void TestPacketFragmentationSize(VideoFormat format, bool with_fec); - void SendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first); - enum { kNumSendSsrcs = 3 }; - static const uint8_t kSendPayloadType; - static const uint8_t kSendRtxPayloadType; - static const uint8_t kFakeSendPayloadType; - static const uint32_t kSendSsrc; - static const uint32_t kSendRtxSsrc; - static const uint32_t kSendSsrcs[kNumSendSsrcs]; - - VideoSendStream::Config send_config_; - std::vector video_streams_; - VideoSendStream* send_stream_; - test::FakeEncoder fake_encoder_; }; -const uint8_t VideoSendStreamTest::kSendPayloadType = 100; -const uint8_t VideoSendStreamTest::kFakeSendPayloadType = 125; -const uint8_t VideoSendStreamTest::kSendRtxPayloadType = 98; -const uint32_t VideoSendStreamTest::kSendRtxSsrc = 0xBADCAFE; -const uint32_t VideoSendStreamTest::kSendSsrcs[kNumSendSsrcs] = { - 0xC0FFED, 0xC0FFEE, 0xC0FFEF}; -const uint32_t VideoSendStreamTest::kSendSsrc = - VideoSendStreamTest::kSendSsrcs[0]; - void VideoSendStreamTest::SendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first) { - class SendSsrcObserver : public test::RtpRtcpObserver { + class SendsSetSsrcs : public test::SendTest { public: - SendSsrcObserver(const uint32_t* ssrcs, - size_t num_ssrcs, - bool send_single_ssrc_first) - : RtpRtcpObserver(30 * 1000), + SendsSetSsrcs(const uint32_t* ssrcs, + size_t num_ssrcs, + bool send_single_ssrc_first) + : SendTest(kDefaultTimeoutMs), + num_ssrcs_(num_ssrcs), + send_single_ssrc_first_(send_single_ssrc_first), ssrcs_to_observe_(num_ssrcs), expect_single_ssrc_(send_single_ssrc_first) { for (size_t i = 0; i < num_ssrcs; ++i) valid_ssrcs_[ssrcs[i]] = true; } + private: virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { RTPHeader header; EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); // TODO(pbos): Reenable this part of the test when #1695 is resolved and - // all SSRCs are allocated on startup. This test was observed - // to fail on TSan as the codec gets set before the SSRCs are - // set up and some frames are sent on a random-generated SSRC + // all SSRCs are allocated on startup. This test was + // observed + // to fail on TSan as the codec gets set before the SSRCs + // are + // set up and some frames are sent on a random-generated + // SSRC // before the correct SSRC gets set. // EXPECT_TRUE(valid_ssrcs_[header.ssrc]) // << "Received unknown SSRC: " << header.ssrc; @@ -169,98 +114,100 @@ void VideoSendStreamTest::SendsSetSsrcs(size_t num_ssrcs, return SEND_PACKET; } + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + if (num_ssrcs_ > 1) { + // Set low simulcast bitrates to not have to wait for bandwidth ramp-up. + for (size_t i = 0; i < video_streams->size(); ++i) { + (*video_streams)[i].min_bitrate_bps = 10000; + (*video_streams)[i].target_bitrate_bps = 10000; + (*video_streams)[i].max_bitrate_bps = 10000; + } + } + + all_streams_ = *video_streams; + if (send_single_ssrc_first_) + video_streams->resize(1); + } + + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) OVERRIDE { + send_stream_ = send_stream; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, 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(all_streams_, NULL); + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting on additional SSRCs."; + } + } + private: std::map valid_ssrcs_; std::map is_observed_; + + const size_t num_ssrcs_; + const bool send_single_ssrc_first_; + size_t ssrcs_to_observe_; bool expect_single_ssrc_; - } observer(kSendSsrcs, num_ssrcs, send_single_ssrc_first); - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); + VideoSendStream* send_stream_; + std::vector all_streams_; + } test(kSendSsrcs, num_ssrcs, send_single_ssrc_first); - CreateTestConfig(call.get(), num_ssrcs); - - if (num_ssrcs > 1) { - // Set low simulcast bitrates to not have to wait for bandwidth ramp-up. - for (size_t i = 0; i < video_streams_.size(); ++i) { - video_streams_[i].min_bitrate_bps = 10000; - video_streams_[i].target_bitrate_bps = 10000; - video_streams_[i].max_bitrate_bps = 10000; - } - } - - std::vector all_streams = video_streams_; - if (send_single_ssrc_first) - video_streams_.resize(1); - - send_stream_ = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create( - send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); - send_stream_->Start(); - frame_generator_capturer->Start(); - - EXPECT_EQ(kEventSignaled, observer.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(all_streams, NULL); - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while waiting on additional SSRCs."; - } - - observer.StopSending(); - frame_generator_capturer->Stop(); - send_stream_->Stop(); - call->DestroyVideoSendStream(send_stream_); + RunBaseTest(&test); } TEST_F(VideoSendStreamTest, CanStartStartedStream) { test::NullTransport transport; Call::Config call_config(&transport); - scoped_ptr call(Call::Create(call_config)); + CreateSenderCall(call_config); - CreateTestConfig(call.get(), 1); - VideoSendStream* stream = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - stream->Start(); - stream->Start(); - call->DestroyVideoSendStream(stream); + CreateSendConfig(1); + CreateStreams(); + send_stream_->Start(); + send_stream_->Start(); + DestroyStreams(); } TEST_F(VideoSendStreamTest, CanStopStoppedStream) { test::NullTransport transport; Call::Config call_config(&transport); - scoped_ptr call(Call::Create(call_config)); + CreateSenderCall(call_config); - CreateTestConfig(call.get(), 1); - VideoSendStream* stream = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - stream->Stop(); - stream->Stop(); - call->DestroyVideoSendStream(stream); + CreateSendConfig(1); + CreateStreams(); + send_stream_->Stop(); + send_stream_->Stop(); + DestroyStreams(); } TEST_F(VideoSendStreamTest, SendsSetSsrc) { SendsSetSsrcs(1, false); } TEST_F(VideoSendStreamTest, DISABLED_SendsSetSimulcastSsrcs) { - SendsSetSsrcs(kNumSendSsrcs, false); + SendsSetSsrcs(kNumSsrcs, false); } TEST_F(VideoSendStreamTest, DISABLED_CanSwitchToUseAllSsrcs) { - SendsSetSsrcs(kNumSendSsrcs, true); + SendsSetSsrcs(kNumSsrcs, true); } TEST_F(VideoSendStreamTest, SupportsCName) { static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo="; - class CNameObserver : public test::RtpRtcpObserver { + class CNameObserver : public test::SendTest { public: - CNameObserver() : RtpRtcpObserver(30 * 1000) {} + CNameObserver() : SendTest(kDefaultTimeoutMs) {} + private: virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { RTCPUtility::RTCPParserV2 parser(packet, length, true); EXPECT_TRUE(parser.IsValid()); @@ -277,22 +224,28 @@ TEST_F(VideoSendStreamTest, SupportsCName) { return SEND_PACKET; } - } observer; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.c_name = kCName; + } - CreateTestConfig(call.get(), 1); - send_config_.rtp.c_name = kCName; + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for RTCP with CNAME."; + } + } test; - RunSendTest(call.get(), &observer); + RunBaseTest(&test); } TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) { static const uint8_t kAbsSendTimeExtensionId = 13; - class AbsoluteSendTimeObserver : public test::RtpRtcpObserver { + class AbsoluteSendTimeObserver : public test::SendTest { public: - AbsoluteSendTimeObserver() : RtpRtcpObserver(30 * 1000) { + AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) { EXPECT_TRUE(parser_->RegisterRtpHeaderExtension( kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId)); } @@ -309,41 +262,35 @@ TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) { return SEND_PACKET; } - } observer; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.extensions.push_back( + RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); + } + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for single RTP packet."; + } - CreateTestConfig(call.get(), 1); - send_config_.rtp.extensions.push_back( - RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); + } test; - RunSendTest(call.get(), &observer); + RunBaseTest(&test); } TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { static const uint8_t kTOffsetExtensionId = 13; - class DelayedEncoder : public test::FakeEncoder { + class TransmissionTimeOffsetObserver : public test::SendTest { public: - explicit DelayedEncoder(Clock* clock) : test::FakeEncoder(clock) {} - virtual int32_t Encode(const I420VideoFrame& input_image, - const CodecSpecificInfo* codec_specific_info, - const std::vector* frame_types) - OVERRIDE { - // A delay needs to be introduced to assure that we get a timestamp - // offset. - SleepMs(5); - return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); - } - } encoder(Clock::GetRealTimeClock()); - - class TransmissionTimeOffsetObserver : public test::RtpRtcpObserver { - public: - TransmissionTimeOffsetObserver() : RtpRtcpObserver(30 * 1000) { + TransmissionTimeOffsetObserver() + : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) { EXPECT_TRUE(parser_->RegisterRtpHeaderExtension( kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId)); } + private: virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { RTPHeader header; EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); @@ -356,17 +303,40 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { return SEND_PACKET; } - } observer; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->encoder_settings.encoder = &encoder_; + send_config->rtp.extensions.push_back( + RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId)); + } - CreateTestConfig(call.get(), 1); - send_config_.encoder_settings.encoder = &encoder; - send_config_.rtp.extensions.push_back( - RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId)); + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting single RTP packet."; + } - RunSendTest(call.get(), &observer); + class DelayedEncoder : public test::FakeEncoder { + public: + explicit DelayedEncoder(Clock* clock) : test::FakeEncoder(clock) {} + virtual int32_t Encode( + const I420VideoFrame& input_image, + const CodecSpecificInfo* codec_specific_info, + const std::vector* frame_types) OVERRIDE { + // A delay needs to be introduced to assure that we get a timestamp + // offset. + SleepMs(5); + return FakeEncoder::Encode( + input_image, codec_specific_info, frame_types); + } + }; + + DelayedEncoder encoder_; + } test; + + RunBaseTest(&test); } class FakeReceiveStatistics : public NullReceiveStatistics { @@ -433,32 +403,31 @@ TEST_F(VideoSendStreamTest, SwapsI420VideoFrames) { test::NullTransport transport; Call::Config call_config(&transport); - scoped_ptr call(Call::Create(call_config)); + CreateSenderCall(call_config); - CreateTestConfig(call.get(), 1); - VideoSendStream* video_send_stream = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - video_send_stream->Start(); + CreateSendConfig(1); + CreateStreams(); + send_stream_->Start(); I420VideoFrame frame; frame.CreateEmptyFrame( kWidth, kHeight, kWidth, (kWidth + 1) / 2, (kWidth + 1) / 2); uint8_t* old_y_buffer = frame.buffer(kYPlane); - video_send_stream->Input()->SwapFrame(&frame); + send_stream_->Input()->SwapFrame(&frame); EXPECT_NE(frame.buffer(kYPlane), old_y_buffer); - call->DestroyVideoSendStream(video_send_stream); + DestroyStreams(); } TEST_F(VideoSendStreamTest, SupportsFec) { static const int kRedPayloadType = 118; static const int kUlpfecPayloadType = 119; - class FecObserver : public test::RtpRtcpObserver { + class FecObserver : public test::SendTest { public: FecObserver() - : RtpRtcpObserver(30 * 1000), + : SendTest(kDefaultTimeoutMs), transport_adapter_(SendTransport()), send_count_(0), received_media_(false), @@ -466,6 +435,7 @@ TEST_F(VideoSendStreamTest, SupportsFec) { transport_adapter_.Enable(); } + private: virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { RTPHeader header; EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); @@ -474,13 +444,13 @@ TEST_F(VideoSendStreamTest, SupportsFec) { if (send_count_++ % 2 != 0) { // Receive statistics reporting having lost 50% of the packets. FakeReceiveStatistics lossy_receive_stats( - kSendSsrc, header.sequenceNumber, send_count_ / 2, 127); + kSendSsrcs[0], header.sequenceNumber, send_count_ / 2, 127); RTCPSender rtcp_sender( 0, false, Clock::GetRealTimeClock(), &lossy_receive_stats); EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); rtcp_sender.SetRTCPStatus(kRtcpNonCompound); - rtcp_sender.SetRemoteSSRC(kSendSsrc); + rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); RTCPSender::FeedbackState feedback_state; @@ -503,33 +473,35 @@ TEST_F(VideoSendStreamTest, SupportsFec) { return SEND_PACKET; } - private: + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.fec.red_payload_type = kRedPayloadType; + send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets."; + } + internal::TransportAdapter transport_adapter_; int send_count_; bool received_media_; bool received_fec_; - } observer; + } test; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); - - observer.SetReceivers(call->Receiver(), NULL); - - CreateTestConfig(call.get(), 1); - send_config_.rtp.fec.red_payload_type = kRedPayloadType; - send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; - - RunSendTest(call.get(), &observer); + RunBaseTest(&test); } void VideoSendStreamTest::TestNackRetransmission( uint32_t retransmit_ssrc, uint8_t retransmit_payload_type) { - class NackObserver : public test::RtpRtcpObserver { + class NackObserver : public test::SendTest { public: explicit NackObserver(uint32_t retransmit_ssrc, uint8_t retransmit_payload_type) - : RtpRtcpObserver(30 * 1000), + : SendTest(kDefaultTimeoutMs), transport_adapter_(SendTransport()), send_count_(0), retransmit_ssrc_(retransmit_ssrc), @@ -538,6 +510,7 @@ void VideoSendStreamTest::TestNackRetransmission( transport_adapter_.Enable(); } + private: virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { RTPHeader header; EXPECT_TRUE(parser_->Parse(packet, static_cast(length), &header)); @@ -552,7 +525,7 @@ void VideoSendStreamTest::TestNackRetransmission( EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); rtcp_sender.SetRTCPStatus(kRtcpNonCompound); - rtcp_sender.SetRemoteSSRC(kSendSsrc); + rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); RTCPSender::FeedbackState feedback_state; @@ -563,8 +536,10 @@ void VideoSendStreamTest::TestNackRetransmission( uint16_t sequence_number = header.sequenceNumber; - if (header.ssrc == retransmit_ssrc_ && retransmit_ssrc_ != kSendSsrc) { - // Not kSendSsrc, assume correct RTX packet. Extract sequence number. + if (header.ssrc == retransmit_ssrc_ && + retransmit_ssrc_ != kSendSsrcs[0]) { + // Not kSendSsrcs[0], assume correct RTX packet. Extract sequence + // number. const uint8_t* rtx_header = packet + header.headerLength; sequence_number = (rtx_header[0] << 8) + rtx_header[1]; } @@ -578,30 +553,34 @@ void VideoSendStreamTest::TestNackRetransmission( return SEND_PACKET; } - private: + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.nack.rtp_history_ms = 1000; + send_config->rtp.rtx.payload_type = retransmit_payload_type_; + if (retransmit_ssrc_ != kSendSsrcs[0]) + send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_); + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for NACK retransmission."; + } + internal::TransportAdapter transport_adapter_; int send_count_; uint32_t retransmit_ssrc_; uint8_t retransmit_payload_type_; int nacked_sequence_number_; - } observer(retransmit_ssrc, retransmit_payload_type); + } test(retransmit_ssrc, retransmit_payload_type); - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); - observer.SetReceivers(call->Receiver(), NULL); - - CreateTestConfig(call.get(), 1); - send_config_.rtp.nack.rtp_history_ms = 1000; - send_config_.rtp.rtx.payload_type = retransmit_payload_type; - if (retransmit_ssrc != kSendSsrc) - send_config_.rtp.rtx.ssrcs.push_back(retransmit_ssrc); - - RunSendTest(call.get(), &observer); + RunBaseTest(&test); } TEST_F(VideoSendStreamTest, RetransmitsNack) { // Normal NACKs should use the send SSRC. - TestNackRetransmission(kSendSsrc, kFakeSendPayloadType); + TestNackRetransmission(kSendSsrcs[0], kFakeSendPayloadType); } TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) { @@ -611,22 +590,28 @@ TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) { void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, bool with_fec) { + // Use a fake encoder to output a frame of every size in the range [90, 290], + // for each size making sure that the exact number of payload bytes received + // is correct and that packets are fragmented to respect max packet size. + static const uint32_t kMaxPacketSize = 128; + static const uint32_t start = 90; + static const uint32_t stop = 290; + static const int kRedPayloadType = 118; static const int kUlpfecPayloadType = 119; // Observer that verifies that the expected number of packets and bytes // arrive for each frame size, from start_size to stop_size. - class FrameFragmentationObserver : public test::RtpRtcpObserver, - public EncodedFrameObserver { + class FrameFragmentationTest : public test::SendTest, + public EncodedFrameObserver { public: - FrameFragmentationObserver(uint32_t max_packet_size, - uint32_t start_size, - uint32_t stop_size, - test::ConfigurableFrameSizeEncoder* encoder, - bool test_generic_packetization, - bool use_fec) - : RtpRtcpObserver(120 * 1000), // Timeout after two minutes. + FrameFragmentationTest(uint32_t max_packet_size, + uint32_t start_size, + uint32_t stop_size, + bool test_generic_packetization, + bool use_fec) + : SendTest(kLongTimeoutMs), transport_adapter_(SendTransport()), - encoder_(encoder), + encoder_(stop), max_packet_size_(max_packet_size), stop_size_(stop_size), test_generic_packetization_(test_generic_packetization), @@ -638,10 +623,12 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, current_size_rtp_(start_size), current_size_frame_(start_size) { // Fragmentation required, this test doesn't make sense without it. + encoder_.SetFrameSize(start); assert(stop_size > max_packet_size); transport_adapter_.Enable(); } + private: virtual Action OnSendRtp(const uint8_t* packet, size_t size) OVERRIDE { uint32_t length = static_cast(size); RTPHeader header; @@ -717,13 +704,13 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, if (packet_count_++ % 2 != 0) { // Receive statistics reporting having lost 50% of the packets. FakeReceiveStatistics lossy_receive_stats( - kSendSsrc, header.sequenceNumber, packet_count_ / 2, 127); + kSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127); RTCPSender rtcp_sender( 0, false, Clock::GetRealTimeClock(), &lossy_receive_stats); EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); rtcp_sender.SetRTCPStatus(kRtcpNonCompound); - rtcp_sender.SetRemoteSSRC(kSendSsrc); + rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); RTCPSender::FeedbackState feedback_state; @@ -738,12 +725,39 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, current_size_frame_.Value() < static_cast(stop_size_)) { ++current_size_frame_; } - encoder_->SetFrameSize(current_size_frame_.Value()); + encoder_.SetFrameSize(current_size_frame_.Value()); + } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + if (use_fec_) { + send_config->rtp.fec.red_payload_type = kRedPayloadType; + send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; + } + + if (!test_generic_packetization_) + send_config->encoder_settings.payload_name = "VP8"; + + send_config->encoder_settings.encoder = &encoder_; + send_config->rtp.max_packet_size = kMaxPacketSize; + send_config->post_encode_callback = this; + + // Add an extension header, to make the RTP header larger than the base + // length of 12 bytes. + static const uint8_t kAbsSendTimeExtensionId = 13; + send_config->rtp.extensions.push_back( + RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while observing incoming RTP packets."; } - private: internal::TransportAdapter transport_adapter_; - test::ConfigurableFrameSizeEncoder* const encoder_; + test::ConfigurableFrameSizeEncoder encoder_; const uint32_t max_packet_size_; const uint32_t stop_size_; @@ -759,45 +773,12 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, Atomic32 current_size_frame_; }; - // Use a fake encoder to output a frame of every size in the range [90, 290], - // for each size making sure that the exact number of payload bytes received - // is correct and that packets are fragmented to respect max packet size. - static const uint32_t kMaxPacketSize = 128; - static const uint32_t start = 90; - static const uint32_t stop = 290; - // Don't auto increment if FEC is used; continue sending frame size until // a FEC packet has been received. - test::ConfigurableFrameSizeEncoder encoder(stop); - encoder.SetFrameSize(start); + FrameFragmentationTest test( + kMaxPacketSize, start, stop, format == kGeneric, with_fec); - FrameFragmentationObserver observer( - kMaxPacketSize, start, stop, &encoder, format == kGeneric, with_fec); - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); - - observer.SetReceivers(call->Receiver(), NULL); - - CreateTestConfig(call.get(), 1); - if (with_fec) { - send_config_.rtp.fec.red_payload_type = kRedPayloadType; - send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; - } - - if (format == kVP8) - send_config_.encoder_settings.payload_name = "VP8"; - - send_config_.encoder_settings.encoder = &encoder; - send_config_.rtp.max_packet_size = kMaxPacketSize; - send_config_.post_encode_callback = &observer; - - // Add an extension header, to make the RTP header larger than the base - // length of 12 bytes. - static const uint8_t kAbsSendTimeExtensionId = 13; - send_config_.rtp.extensions.push_back( - RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); - - RunSendTest(call.get(), &observer); + RunBaseTest(&test); } // TODO(sprang): Is there any way of speeding up these tests? @@ -829,13 +810,12 @@ TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) { TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps. - class RembObserver : public test::RtpRtcpObserver, public I420FrameCallback { + class RembObserver : public test::SendTest, public I420FrameCallback { public: - RembObserver(VideoSendStream** send_stream_ptr) - : RtpRtcpObserver(30 * 1000), // Timeout after 30 seconds. + RembObserver() + : SendTest(kDefaultTimeoutMs), transport_adapter_(&transport_), clock_(Clock::GetRealTimeClock()), - send_stream_ptr_(send_stream_ptr), crit_(CriticalSectionWrapper::CreateCriticalSection()), test_state_(kBeforeSuspend), rtp_count_(0), @@ -846,10 +826,7 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { transport_adapter_.Enable(); } - void SetReceiver(PacketReceiver* receiver) { - transport_.SetReceiver(receiver); - } - + private: virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { // Receive statistics reporting having lost 0% of the packets. // This is needed for the send-side bitrate controller to work properly. @@ -882,8 +859,7 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { test_state_ = kWaitingForStats; } } else if (test_state_ == kWaitingForStats) { - assert(*send_stream_ptr_); - VideoSendStream::Stats stats = (*send_stream_ptr_)->GetStats(); + VideoSendStream::Stats stats = stream_->GetStats(); if (stats.suspended == false) { // Stats flipped to false. Test is complete. observation_complete_->Set(); @@ -898,8 +874,7 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { CriticalSectionScoped lock(crit_.get()); if (test_state_ == kDuringSuspend && ++suspended_frame_count_ > kSuspendTimeFrames) { - assert(*send_stream_ptr_); - VideoSendStream::Stats stats = (*send_stream_ptr_)->GetStats(); + VideoSendStream::Stats stats = stream_->GetStats(); EXPECT_TRUE(stats.suspended); SendRtcpFeedback(high_remb_bps_); test_state_ = kWaitingForPacket; @@ -916,9 +891,38 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { high_remb_bps_ = value; } - void Stop() { transport_.StopSending(); } + virtual void SetReceivers( + PacketReceiver* send_transport_receiver, + PacketReceiver* receive_transport_receiver) OVERRIDE { + transport_.SetReceiver(send_transport_receiver); + } + + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) OVERRIDE { + stream_ = send_stream; + } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.nack.rtp_history_ms = 1000; + send_config->pre_encode_callback = this; + send_config->suspend_below_min_bitrate = true; + int min_bitrate_bps = (*video_streams)[0].min_bitrate_bps; + set_low_remb_bps(min_bitrate_bps - 10000); + int threshold_window = std::max(min_bitrate_bps / 10, 10000); + ASSERT_GT((*video_streams)[0].max_bitrate_bps, + min_bitrate_bps + threshold_window + 5000); + set_high_remb_bps(min_bitrate_bps + threshold_window + 5000); + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out during suspend-below-min-bitrate test."; + transport_.StopSending(); + } - private: enum TestState { kBeforeSuspend, kDuringSuspend, @@ -929,12 +933,12 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { virtual void SendRtcpFeedback(int remb_value) EXCLUSIVE_LOCKS_REQUIRED(crit_) { FakeReceiveStatistics receive_stats( - kSendSsrc, last_sequence_number_, rtp_count_, 0); + kSendSsrcs[0], last_sequence_number_, rtp_count_, 0); RTCPSender rtcp_sender(0, false, clock_, &receive_stats); EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); rtcp_sender.SetRTCPStatus(kRtcpNonCompound); - rtcp_sender.SetRemoteSSRC(kSendSsrc); + rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); if (remb_value > 0) { rtcp_sender.SetREMBStatus(true); rtcp_sender.SetREMBData(remb_value, 0, NULL); @@ -946,7 +950,7 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { internal::TransportAdapter transport_adapter_; test::DirectTransport transport_; Clock* const clock_; - VideoSendStream** const send_stream_ptr_; + VideoSendStream* stream_; const scoped_ptr crit_; TestState test_state_ GUARDED_BY(crit_); @@ -955,34 +959,16 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { int suspended_frame_count_ GUARDED_BY(crit_); int low_remb_bps_ GUARDED_BY(crit_); int high_remb_bps_ GUARDED_BY(crit_); - } observer(&send_stream_); - // Note that |send_stream_| is created in RunSendTest(), called below. This - // is why a pointer to |send_stream_| must be provided here. + } test; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); - observer.SetReceiver(call->Receiver()); - - CreateTestConfig(call.get(), 1); - send_config_.rtp.nack.rtp_history_ms = 1000; - send_config_.pre_encode_callback = &observer; - send_config_.suspend_below_min_bitrate = true; - int min_bitrate_bps = video_streams_[0].min_bitrate_bps; - observer.set_low_remb_bps(min_bitrate_bps - 10000); - int threshold_window = std::max(min_bitrate_bps / 10, 10000); - ASSERT_GT(video_streams_[0].max_bitrate_bps, - min_bitrate_bps + threshold_window + 5000); - observer.set_high_remb_bps(min_bitrate_bps + threshold_window + 5000); - - RunSendTest(call.get(), &observer); - observer.Stop(); + RunBaseTest(&test); } TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) { - class PacketObserver : public test::RtpRtcpObserver { + class NoPaddingWhenVideoIsMuted : public test::SendTest { public: - PacketObserver() - : RtpRtcpObserver(30 * 1000), // Timeout after 30 seconds. + NoPaddingWhenVideoIsMuted() + : SendTest(kDefaultTimeoutMs), clock_(Clock::GetRealTimeClock()), transport_adapter_(ReceiveTransport()), crit_(CriticalSectionWrapper::CreateCriticalSection()), @@ -991,11 +977,7 @@ TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) { transport_adapter_.Enable(); } - void SetCapturer(test::FrameGeneratorCapturer* capturer) { - CriticalSectionScoped lock(crit_.get()); - capturer_ = capturer; - } - + private: virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { CriticalSectionScoped lock(crit_.get()); last_packet_time_ms_ = clock_->TimeInMilliseconds(); @@ -1025,46 +1007,43 @@ TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) { return SEND_PACKET; } - private: + virtual void SetReceivers( + PacketReceiver* send_transport_receiver, + PacketReceiver* receive_transport_receiver) OVERRIDE { + RtpRtcpObserver::SetReceivers(send_transport_receiver, + send_transport_receiver); + } + + virtual size_t GetNumStreams() const OVERRIDE { return 3; } + + virtual void OnFrameGeneratorCapturerCreated( + test::FrameGeneratorCapturer* frame_generator_capturer) { + CriticalSectionScoped lock(crit_.get()); + capturer_ = frame_generator_capturer; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for RTP packets to stop being sent."; + } + Clock* const clock_; internal::TransportAdapter transport_adapter_; const scoped_ptr crit_; int64_t last_packet_time_ms_ GUARDED_BY(crit_); test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_); - } observer; + } test; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); - observer.SetReceivers(call->Receiver(), call->Receiver()); - - CreateTestConfig(call.get(), 3); - - send_stream_ = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create( - send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); - observer.SetCapturer(frame_generator_capturer.get()); - send_stream_->Start(); - frame_generator_capturer->Start(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timed out while waiting for RTP packets to stop being sent."; - - observer.StopSending(); - frame_generator_capturer->Stop(); - send_stream_->Stop(); - call->DestroyVideoSendStream(send_stream_); + RunBaseTest(&test); } TEST_F(VideoSendStreamTest, ProducesStats) { static const std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo="; - static const uint32_t kTimeoutMs = 30 * 1000; - class StatsObserver : public test::RtpRtcpObserver { + class ProducesStats : public test::SendTest { public: - StatsObserver() - : RtpRtcpObserver(kTimeoutMs), + ProducesStats() + : SendTest(kDefaultTimeoutMs), stream_(NULL), event_(EventWrapper::Create()) {} @@ -1074,10 +1053,11 @@ TEST_F(VideoSendStreamTest, ProducesStats) { return SEND_PACKET; } + private: bool WaitForFilledStats() { Clock* clock = Clock::GetRealTimeClock(); int64_t now = clock->TimeInMilliseconds(); - int64_t stop_time = now + kTimeoutMs; + int64_t stop_time = now + kDefaultTimeoutMs; while (now < stop_time) { int64_t time_left = stop_time - now; if (time_left > 0 && event_->Wait(time_left) == kEventSignaled && @@ -1113,36 +1093,30 @@ TEST_F(VideoSendStreamTest, ProducesStats) { void SetConfig(const VideoSendStream::Config& config) { config_ = config; } - void SetSendStream(VideoSendStream* stream) { stream_ = stream; } + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.c_name = kCName; + SetConfig(*send_config); + } + + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) OVERRIDE { + stream_ = send_stream; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_TRUE(WaitForFilledStats()) + << "Timed out waiting for filled statistics."; + } VideoSendStream* stream_; VideoSendStream::Config config_; scoped_ptr event_; - } observer; + } test; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); - - CreateTestConfig(call.get(), 1); - send_config_.rtp.c_name = kCName; - observer.SetConfig(send_config_); - - send_stream_ = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - observer.SetSendStream(send_stream_); - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create( - send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); - send_stream_->Start(); - frame_generator_capturer->Start(); - - EXPECT_TRUE(observer.WaitForFilledStats()) - << "Timed out waiting for filled statistics."; - - observer.StopSending(); - frame_generator_capturer->Stop(); - send_stream_->Stop(); - call->DestroyVideoSendStream(send_stream_); + RunBaseTest(&test); } // This test first observes "high" bitrate use at which point it sends a REMB to @@ -1157,12 +1131,11 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) { static const int kHighBitrateBps = 150000; static const int kRembBitrateBps = 80000; static const int kRembRespectedBitrateBps = 100000; - class BitrateObserver: public test::RtpRtcpObserver, public PacketReceiver { + class BitrateObserver : public test::SendTest, public PacketReceiver { public: BitrateObserver() - : RtpRtcpObserver(30 * 1000), + : SendTest(kDefaultTimeoutMs), feedback_transport_(ReceiveTransport()), - send_stream_(NULL), bitrate_capped_(false) { RtpRtcp::Configuration config; feedback_transport_.Enable(); @@ -1172,8 +1145,9 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) { rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); } - void SetSendStream(VideoSendStream* send_stream) { - send_stream_ = send_stream; + virtual void OnStreamsCreated(VideoSendStream* send_stream, + VideoReceiveStream* receive_stream) OVERRIDE { + stream_ = send_stream; } private: @@ -1185,8 +1159,8 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) { RTPHeader header; if (!parser_->Parse(packet, static_cast(length), &header)) return DELIVERY_PACKET_ERROR; - assert(send_stream_ != NULL); - VideoSendStream::Stats stats = send_stream_->GetStats(); + assert(stream_ != NULL); + VideoSendStream::Stats stats = stream_->GetStats(); if (!stats.substreams.empty()) { EXPECT_EQ(1u, stats.substreams.size()); int bitrate_bps = stats.substreams.begin()->second.bitrate_bps; @@ -1209,35 +1183,31 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) { return DELIVERY_OK; } + virtual void SetReceivers( + PacketReceiver* send_transport_receiver, + PacketReceiver* receive_transport_receiver) OVERRIDE { + RtpRtcpObserver::SetReceivers(this, send_transport_receiver); + } + + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + VideoReceiveStream::Config* receive_config, + std::vector* video_streams) OVERRIDE { + send_config->rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timeout while waiting for low bitrate stats after REMB."; + } + scoped_ptr rtp_rtcp_; internal::TransportAdapter feedback_transport_; - VideoSendStream* send_stream_; + VideoSendStream* stream_; bool bitrate_capped_; - } observer; + } test; - Call::Config call_config(observer.SendTransport()); - scoped_ptr call(Call::Create(call_config)); - observer.SetReceivers(&observer, call->Receiver()); - - CreateTestConfig(call.get(), 1); - send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps; - send_stream_ = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); - observer.SetSendStream(send_stream_); - - scoped_ptr frame_generator_capturer( - test::FrameGeneratorCapturer::Create( - send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); - send_stream_->Start(); - frame_generator_capturer->Start(); - - EXPECT_EQ(kEventSignaled, observer.Wait()) - << "Timeout while waiting for low bitrate stats after REMB."; - - observer.StopSending(); - frame_generator_capturer->Stop(); - send_stream_->Stop(); - call->DestroyVideoSendStream(send_stream_); + RunBaseTest(&test); } TEST_F(VideoSendStreamTest, CapturesTextureAndI420VideoFrames) { @@ -1271,13 +1241,12 @@ TEST_F(VideoSendStreamTest, CapturesTextureAndI420VideoFrames) { // Initialize send stream. test::NullTransport transport; - Call::Config call_config(&transport); - scoped_ptr call(Call::Create(call_config)); - CreateTestConfig(call.get(), 1); + CreateSenderCall(Call::Config(&transport)); + + CreateSendConfig(1); FrameObserver observer; send_config_.pre_encode_callback = &observer; - send_stream_ = - call->CreateVideoSendStream(send_config_, video_streams_, NULL); + CreateStreams(); // Prepare five input frames. Send I420VideoFrame and TextureVideoFrame // alternatively. @@ -1314,7 +1283,7 @@ TEST_F(VideoSendStreamTest, CapturesTextureAndI420VideoFrames) { // timestamp are not compared because capturer sets those values. ExpectEqualFramesVector(input_frames.get(), observer.output_frames()); - call->DestroyVideoSendStream(send_stream_); + DestroyStreams(); } void ExpectEqualFrames(const I420VideoFrame& frame1, diff --git a/webrtc/webrtc_tests.gypi b/webrtc/webrtc_tests.gypi index 3c1dca69e..85a7e733b 100644 --- a/webrtc/webrtc_tests.gypi +++ b/webrtc/webrtc_tests.gypi @@ -46,7 +46,7 @@ 'type': '<(gtest_target_type)', 'sources': [ 'video/bitrate_estimator_tests.cc', - 'video/call_tests.cc', + 'video/end_to_end_tests.cc', 'video/send_statistics_proxy_unittest.cc', 'video/video_send_stream_tests.cc', 'test/common_unittest.cc',