Add unit test of AudioRtpReceiver
Bug: chromium:1272566
Change-Id: Ic10c586062cc8fdded2dd6249b49fab527c99823
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/238987
Commit-Queue: Tony Herre <toprice@chromium.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35429}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index f31109a..f29b558 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -874,6 +874,7 @@
testonly = true
sources = [
+ "audio_rtp_receiver_unittest.cc",
"channel_manager_unittest.cc",
"channel_unittest.cc",
"dtls_srtp_transport_unittest.cc",
@@ -902,6 +903,7 @@
}
deps = [
+ ":audio_rtp_receiver",
":libjingle_peerconnection",
":pc_test_utils",
":peerconnection",
@@ -939,6 +941,7 @@
"../rtc_base/third_party/sigslot",
"../system_wrappers:metrics",
"../test:field_trial",
+ "../test:test_common",
"../test:test_main",
"../test:test_support",
"//third_party/abseil-cpp/absl/algorithm:container",
@@ -1345,6 +1348,7 @@
"test/mock_peer_connection_observers.h",
"test/mock_rtp_receiver_internal.h",
"test/mock_rtp_sender_internal.h",
+ "test/mock_voice_media_channel.h",
"test/peer_connection_test_wrapper.cc",
"test/peer_connection_test_wrapper.h",
"test/rtc_stats_obtainer.h",
diff --git a/pc/audio_rtp_receiver.cc b/pc/audio_rtp_receiver.cc
index cfaee40..7890d9b 100644
--- a/pc/audio_rtp_receiver.cc
+++ b/pc/audio_rtp_receiver.cc
@@ -167,8 +167,10 @@
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
RTC_DCHECK_RUN_ON(worker_thread_);
+
if (media_channel_)
SetOutputVolume_w(0.0);
+
SetMediaChannel_w(nullptr);
});
}
diff --git a/pc/audio_rtp_receiver_unittest.cc b/pc/audio_rtp_receiver_unittest.cc
new file mode 100644
index 0000000..1865115
--- /dev/null
+++ b/pc/audio_rtp_receiver_unittest.cc
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2021 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 "pc/audio_rtp_receiver.h"
+
+#include "media/base/media_channel.h"
+#include "pc/test/mock_voice_media_channel.h"
+#include "rtc_base/gunit.h"
+#include "rtc_base/thread.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using ::testing::_;
+using ::testing::InvokeWithoutArgs;
+using ::testing::Mock;
+
+static const int kTimeOut = 100;
+static const double kDefaultVolume = 1;
+static const double kVolume = 3.7;
+static const uint32_t kSsrc = 3;
+
+namespace webrtc {
+class AudioRtpReceiverTest : public ::testing::Test {
+ protected:
+ AudioRtpReceiverTest()
+ : worker_(rtc::Thread::Current()),
+ receiver_(
+ rtc::make_ref_counted<AudioRtpReceiver>(worker_,
+ std::string(),
+ std::vector<std::string>(),
+ false)),
+ media_channel_(rtc::Thread::Current()) {
+ EXPECT_CALL(media_channel_, SetRawAudioSink(kSsrc, _));
+ EXPECT_CALL(media_channel_, SetBaseMinimumPlayoutDelayMs(kSsrc, _));
+ }
+
+ ~AudioRtpReceiverTest() {
+ receiver_->SetMediaChannel(nullptr);
+ receiver_->Stop();
+ }
+
+ rtc::Thread* worker_;
+ rtc::scoped_refptr<AudioRtpReceiver> receiver_;
+ cricket::MockVoiceMediaChannel media_channel_;
+};
+
+TEST_F(AudioRtpReceiverTest, SetOutputVolumeIsCalled) {
+ std::atomic_int set_volume_calls(0);
+
+ EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kDefaultVolume))
+ .WillOnce(InvokeWithoutArgs([&] {
+ set_volume_calls++;
+ return true;
+ }));
+
+ receiver_->track();
+ receiver_->track()->set_enabled(true);
+ receiver_->SetMediaChannel(&media_channel_);
+ receiver_->SetupMediaChannel(kSsrc);
+
+ EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kVolume))
+ .WillOnce(InvokeWithoutArgs([&] {
+ set_volume_calls++;
+ return true;
+ }));
+
+ receiver_->OnSetVolume(kVolume);
+ EXPECT_TRUE_WAIT(set_volume_calls == 2, kTimeOut);
+}
+
+TEST_F(AudioRtpReceiverTest, VolumesSetBeforeStartingAreRespected) {
+ // Set the volume before setting the media channel. It should still be used
+ // as the initial volume.
+ receiver_->OnSetVolume(kVolume);
+
+ receiver_->track()->set_enabled(true);
+ receiver_->SetMediaChannel(&media_channel_);
+
+ // The previosly set initial volume should be propagated to the provided
+ // media_channel_ as soon as SetupMediaChannel is called.
+ EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kVolume));
+
+ receiver_->SetupMediaChannel(kSsrc);
+}
+} // namespace webrtc
diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h
new file mode 100644
index 0000000..d6756b1
--- /dev/null
+++ b/pc/test/mock_voice_media_channel.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2021 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 PC_TEST_MOCK_VOICE_MEDIA_CHANNEL_H_
+#define PC_TEST_MOCK_VOICE_MEDIA_CHANNEL_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "media/base/media_channel.h"
+#include "rtc_base/gunit.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using ::testing::InvokeWithoutArgs;
+using ::testing::Mock;
+
+namespace cricket {
+class MockVoiceMediaChannel : public VoiceMediaChannel {
+ public:
+ explicit MockVoiceMediaChannel(webrtc::TaskQueueBase* network_thread)
+ : VoiceMediaChannel(network_thread) {}
+
+ MOCK_METHOD(void, SetInterface, (NetworkInterface * iface), (override));
+ MOCK_METHOD(void,
+ OnPacketReceived,
+ (rtc::CopyOnWriteBuffer packet, int64_t packet_time_us),
+ (override));
+ MOCK_METHOD(void,
+ OnPacketSent,
+ (const rtc::SentPacket& sent_packet),
+ (override));
+ MOCK_METHOD(void, OnReadyToSend, (bool ready), (override));
+ MOCK_METHOD(void,
+ OnNetworkRouteChanged,
+ (const std::string& transport_name,
+ const rtc::NetworkRoute& network_route),
+ (override));
+ MOCK_METHOD(bool, AddSendStream, (const StreamParams& sp), (override));
+ MOCK_METHOD(bool, RemoveSendStream, (uint32_t ssrc), (override));
+ MOCK_METHOD(bool, AddRecvStream, (const StreamParams& sp), (override));
+ MOCK_METHOD(bool, RemoveRecvStream, (uint32_t ssrc), (override));
+ MOCK_METHOD(void, ResetUnsignaledRecvStream, (), (override));
+ MOCK_METHOD(void, OnDemuxerCriteriaUpdatePending, (), (override));
+ MOCK_METHOD(void, OnDemuxerCriteriaUpdateComplete, (), (override));
+ MOCK_METHOD(int, GetRtpSendTimeExtnId, (), (const override));
+ MOCK_METHOD(
+ void,
+ SetFrameEncryptor,
+ (uint32_t ssrc,
+ rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor),
+ (override));
+ MOCK_METHOD(
+ void,
+ SetFrameDecryptor,
+ (uint32_t ssrc,
+ rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor),
+ (override));
+ MOCK_METHOD(void, SetVideoCodecSwitchingEnabled, (bool enabled), (override));
+ MOCK_METHOD(webrtc::RtpParameters,
+ GetRtpSendParameters,
+ (uint32_t ssrc),
+ (const override));
+ MOCK_METHOD(webrtc::RTCError,
+ SetRtpSendParameters,
+ (uint32_t ssrc, const webrtc::RtpParameters& parameters),
+ (override));
+ MOCK_METHOD(
+ void,
+ SetEncoderToPacketizerFrameTransformer,
+ (uint32_t ssrc,
+ rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer),
+ (override));
+ MOCK_METHOD(
+ void,
+ SetDepacketizerToDecoderFrameTransformer,
+ (uint32_t ssrc,
+ rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer),
+ (override));
+
+ MOCK_METHOD(bool,
+ SetSendParameters,
+ (const AudioSendParameters& params),
+ (override));
+ MOCK_METHOD(bool,
+ SetRecvParameters,
+ (const AudioRecvParameters& params),
+ (override));
+ MOCK_METHOD(webrtc::RtpParameters,
+ GetRtpReceiveParameters,
+ (uint32_t ssrc),
+ (const override));
+ MOCK_METHOD(webrtc::RtpParameters,
+ GetDefaultRtpReceiveParameters,
+ (),
+ (const override));
+ MOCK_METHOD(void, SetPlayout, (bool playout), (override));
+ MOCK_METHOD(void, SetSend, (bool send), (override));
+ MOCK_METHOD(bool,
+ SetAudioSend,
+ (uint32_t ssrc,
+ bool enable,
+ const AudioOptions* options,
+ AudioSource* source),
+ (override));
+ MOCK_METHOD(bool,
+ SetOutputVolume,
+ (uint32_t ssrc, double volume),
+ (override));
+ MOCK_METHOD(bool, SetDefaultOutputVolume, (double volume), (override));
+ MOCK_METHOD(bool, CanInsertDtmf, (), (override));
+ MOCK_METHOD(bool,
+ InsertDtmf,
+ (uint32_t ssrc, int event, int duration),
+ (override));
+ MOCK_METHOD(bool,
+ GetStats,
+ (VoiceMediaInfo * info, bool get_and_clear_legacy_stats),
+ (override));
+ MOCK_METHOD(void,
+ SetRawAudioSink,
+ (uint32_t ssrc, std::unique_ptr<webrtc::AudioSinkInterface> sink),
+ (override));
+ MOCK_METHOD(void,
+ SetDefaultRawAudioSink,
+ (std::unique_ptr<webrtc::AudioSinkInterface> sink),
+ (override));
+ MOCK_METHOD(std::vector<webrtc::RtpSource>,
+ GetSources,
+ (uint32_t ssrc),
+ (const override));
+
+ MOCK_METHOD(bool,
+ SetBaseMinimumPlayoutDelayMs,
+ (uint32_t ssrc, int delay_ms),
+ (override));
+ MOCK_METHOD(absl::optional<int>,
+ GetBaseMinimumPlayoutDelayMs,
+ (uint32_t ssrc),
+ (const override));
+};
+} // namespace cricket
+
+#endif // PC_TEST_MOCK_VOICE_MEDIA_CHANNEL_H_