From c68d282250d20b44d0abec33b53e3171f1e25da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Tue, 20 Nov 2018 14:52:05 +0100 Subject: [PATCH] Add test PeerConnectionIntegrationTest.MediaTransportBidirectionalAudio Bug: webrtc:9719 Change-Id: Idbd585c569c54cb86a30f3c30139ad4797dfe723 Reviewed-on: https://webrtc-review.googlesource.com/c/111500 Reviewed-by: Steve Anton Commit-Queue: Niels Moller Cr-Commit-Position: refs/heads/master@{#25719} --- api/test/loopback_media_transport.h | 32 ++++++++++++++++++++++--- pc/peerconnection_integrationtest.cc | 35 ++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/api/test/loopback_media_transport.h b/api/test/loopback_media_transport.h index 2524fb47b1..dbb674db83 100644 --- a/api/test/loopback_media_transport.h +++ b/api/test/loopback_media_transport.h @@ -100,6 +100,11 @@ class WrapperMediaTransportFactory : public MediaTransportFactory { // Currently supports audio only. class MediaTransportPair { public: + struct Stats { + int sent_audio_frames = 0; + int received_audio_frames = 0; + }; + explicit MediaTransportPair(rtc::Thread* thread) : first_(thread, &second_), second_(thread, &first_) {} @@ -125,6 +130,9 @@ class MediaTransportPair { second_.FlushAsyncInvokes(); } + Stats FirstStats() { return first_.GetStats(); } + Stats SecondStats() { return second_.GetStats(); } + private: class LoopbackMediaTransport : public MediaTransportInterface { public: @@ -139,6 +147,10 @@ class MediaTransportPair { RTCError SendAudioFrame(uint64_t channel_id, MediaTransportEncodedAudioFrame frame) override { + { + rtc::CritScope lock(&stats_lock_); + ++stats_.sent_audio_frames; + } invoker_.AsyncInvoke(RTC_FROM_HERE, thread_, [this, channel_id, frame] { other_->OnData(channel_id, std::move(frame)); @@ -215,11 +227,22 @@ class MediaTransportPair { void FlushAsyncInvokes() { invoker_.Flush(thread_); } + Stats GetStats() { + rtc::CritScope lock(&stats_lock_); + return stats_; + } + private: void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame) { - rtc::CritScope lock(&sink_lock_); - if (sink_) { - sink_->OnData(channel_id, frame); + { + rtc::CritScope lock(&sink_lock_); + if (sink_) { + sink_->OnData(channel_id, frame); + } + } + { + rtc::CritScope lock(&stats_lock_); + ++stats_.received_audio_frames; } } @@ -249,6 +272,7 @@ class MediaTransportPair { rtc::Thread* const thread_; rtc::CriticalSection sink_lock_; + rtc::CriticalSection stats_lock_; MediaTransportAudioSinkInterface* sink_ RTC_GUARDED_BY(sink_lock_) = nullptr; @@ -261,6 +285,8 @@ class MediaTransportPair { LoopbackMediaTransport* const other_; + Stats stats_ RTC_GUARDED_BY(stats_lock_); + rtc::AsyncInvoker invoker_; }; diff --git a/pc/peerconnection_integrationtest.cc b/pc/peerconnection_integrationtest.cc index 1e6a28c41d..a7f7aad0f5 100644 --- a/pc/peerconnection_integrationtest.cc +++ b/pc/peerconnection_integrationtest.cc @@ -3492,6 +3492,41 @@ TEST_P(PeerConnectionIntegrationTest, EXPECT_FALSE(callee()->data_channel()->negotiated()); } +TEST_P(PeerConnectionIntegrationTest, MediaTransportBidirectionalAudio) { + PeerConnectionInterface::RTCConfiguration rtc_config; + rtc_config.use_media_transport = true; + rtc_config.enable_dtls_srtp = false; // SDES is required for media transport. + ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory( + rtc_config, rtc_config, loopback_media_transports()->first_factory(), + loopback_media_transports()->second_factory())); + ConnectFakeSignaling(); + + caller()->AddAudioTrack(); + callee()->AddAudioTrack(); + // Start offer/answer exchange and wait for it to complete. + caller()->CreateAndSetAndSignalOffer(); + ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); + + // Ensure that the media transport is ready. + loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable); + loopback_media_transports()->FlushAsyncInvokes(); + + MediaExpectations media_expectations; + media_expectations.ExpectBidirectionalAudio(); + ASSERT_TRUE(ExpectNewFrames(media_expectations)); + + webrtc::MediaTransportPair::Stats first_stats = + loopback_media_transports()->FirstStats(); + webrtc::MediaTransportPair::Stats second_stats = + loopback_media_transports()->SecondStats(); + + EXPECT_GT(first_stats.received_audio_frames, 0); + EXPECT_GE(second_stats.sent_audio_frames, first_stats.received_audio_frames); + + EXPECT_GT(second_stats.received_audio_frames, 0); + EXPECT_GE(first_stats.sent_audio_frames, second_stats.received_audio_frames); +} + // Test that the ICE connection and gathering states eventually reach // "complete". TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {