diff --git a/api/audio/BUILD.gn b/api/audio/BUILD.gn index 710c490948..d4b3b93d54 100644 --- a/api/audio/BUILD.gn +++ b/api/audio/BUILD.gn @@ -167,11 +167,16 @@ rtc_source_set("echo_detector_creator") { if (rtc_include_tests) { rtc_library("audio_api_unittests") { testonly = true - sources = [ "builtin_audio_processing_factory_unittest.cc" ] + sources = [ + "audio_processing_unittest.cc", + "builtin_audio_processing_factory_unittest.cc", + ] deps = [ ":audio_processing", ":builtin_audio_processing_factory", + "..:make_ref_counted", "..:scoped_refptr", + "../../modules/audio_processing:mocks", "../../test:test_support", "../environment", "../environment:environment_factory", diff --git a/api/audio/audio_processing.cc b/api/audio/audio_processing.cc index 2df2a783c3..eab5075ed5 100644 --- a/api/audio/audio_processing.cc +++ b/api/audio/audio_processing.cc @@ -9,8 +9,14 @@ */ #include "api/audio/audio_processing.h" -#include +#include +#include +#include + +#include "absl/base/nullability.h" +#include "api/environment/environment.h" +#include "api/scoped_refptr.h" #include "rtc_base/checks.h" #include "rtc_base/strings/string_builder.h" @@ -208,4 +214,24 @@ std::string AudioProcessing::Config::ToString() const { return builder.str(); } +absl::Nonnull> CustomAudioProcessing( + absl::Nonnull> audio_processing) { + class Factory : public AudioProcessingFactory { + public: + explicit Factory(absl::Nonnull> ap) + : ap_(std::move(ap)) {} + + absl::Nullable> Create( + const Environment& /*env*/) override { + return ap_; + } + + private: + absl::Nonnull> ap_; + }; + + RTC_CHECK(audio_processing); + return std::make_unique(std::move(audio_processing)); +} + } // namespace webrtc diff --git a/api/audio/audio_processing.h b/api/audio/audio_processing.h index a9a82d91a4..99498a4e1d 100644 --- a/api/audio/audio_processing.h +++ b/api/audio/audio_processing.h @@ -742,6 +742,14 @@ class AudioProcessingFactory { const Environment& env) = 0; }; +// Returns factory that always returns the same `audio_processing` ignoring the +// extra construction parameter `env`. +// nullptr `audio_processing` is not supported as in some scenarios that imply +// no audio processing, while in others - default builtin audio processing. +// Callers should be explicit which of these two behaviors they want. +absl::Nonnull> CustomAudioProcessing( + absl::Nonnull> audio_processing); + // Experimental interface for a custom analysis submodule. class CustomAudioAnalyzer { public: diff --git a/api/audio/audio_processing_unittest.cc b/api/audio/audio_processing_unittest.cc new file mode 100644 index 0000000000..92b44715fa --- /dev/null +++ b/api/audio/audio_processing_unittest.cc @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 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 "api/audio/audio_processing.h" + +#include + +#include "api/environment/environment_factory.h" +#include "api/make_ref_counted.h" +#include "api/scoped_refptr.h" +#include "modules/audio_processing/include/mock_audio_processing.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { + +using ::testing::_; +using ::testing::NotNull; + +TEST(CustomAudioProcessingTest, ReturnsTheSameAudioProcessing) { + scoped_refptr ap = + make_ref_counted(); + + std::unique_ptr factory = CustomAudioProcessing(ap); + + ASSERT_THAT(factory, NotNull()); + EXPECT_EQ(factory->Create(CreateEnvironment()), ap); + EXPECT_EQ(factory->Create(CreateEnvironment()), ap); +} + +#if GTEST_HAS_DEATH_TEST +TEST(CustomAudioProcessingTest, NullptrAudioProcessingIsUnsupported) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + EXPECT_DEATH(CustomAudioProcessing(nullptr), _); +#pragma clang diagnostic pop +} +#endif + +} // namespace webrtc diff --git a/api/create_peerconnection_factory.cc b/api/create_peerconnection_factory.cc index 888d1e8a4e..c77e588b6c 100644 --- a/api/create_peerconnection_factory.cc +++ b/api/create_peerconnection_factory.cc @@ -58,8 +58,9 @@ rtc::scoped_refptr CreatePeerConnectionFactory( dependencies.audio_encoder_factory = std::move(audio_encoder_factory); dependencies.audio_decoder_factory = std::move(audio_decoder_factory); dependencies.audio_frame_processor = std::move(audio_frame_processor); - if (audio_processing) { - dependencies.audio_processing = std::move(audio_processing); + if (audio_processing != nullptr) { + dependencies.audio_processing_factory = + CustomAudioProcessing(std::move(audio_processing)); } else { #ifndef WEBRTC_EXCLUDE_AUDIO_PROCESSING_MODULE dependencies.audio_processing_factory = diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn index d728237ffc..d0298af44a 100644 --- a/test/pc/e2e/BUILD.gn +++ b/test/pc/e2e/BUILD.gn @@ -108,6 +108,7 @@ if (!build_with_chromium) { "../../../api:scoped_refptr", "../../../api:time_controller", "../../../api/audio:audio_device", + "../../../api/audio:audio_processing", "../../../api/rtc_event_log:rtc_event_log_factory", "../../../api/task_queue", "../../../api/task_queue:default_task_queue_factory", diff --git a/test/pc/e2e/test_peer_factory.cc b/test/pc/e2e/test_peer_factory.cc index d000b0b422..baafb826f3 100644 --- a/test/pc/e2e/test_peer_factory.cc +++ b/test/pc/e2e/test_peer_factory.cc @@ -18,6 +18,7 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" #include "api/audio/audio_device.h" +#include "api/audio/audio_processing.h" #include "api/peer_connection_interface.h" #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/scoped_refptr.h" @@ -226,7 +227,10 @@ PeerConnectionFactoryDependencies CreatePCFDependencies( // Media dependencies pcf_deps.adm = std::move(audio_device_module); - pcf_deps.audio_processing = pcf_dependencies->audio_processing; + if (pcf_dependencies->audio_processing != nullptr) { + pcf_deps.audio_processing_factory = + CustomAudioProcessing(pcf_dependencies->audio_processing); + } pcf_deps.audio_mixer = pcf_dependencies->audio_mixer; pcf_deps.video_encoder_factory = std::move(pcf_dependencies->video_encoder_factory);