diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 6d464901dc..0443c114e3 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -285,7 +285,7 @@ struct AudioProcessingImpl::ApmPrivateSubmodules { ApmPrivateSubmodules(NonlinearBeamformer* beamformer, std::unique_ptr capture_post_processor, std::unique_ptr render_pre_processor, - std::unique_ptr echo_detector) + rtc::scoped_refptr echo_detector) : beamformer(beamformer), echo_detector(std::move(echo_detector)), capture_post_processor(std::move(capture_post_processor)), @@ -295,7 +295,7 @@ struct AudioProcessingImpl::ApmPrivateSubmodules { std::unique_ptr agc_manager; std::unique_ptr gain_controller2; std::unique_ptr low_cut_filter; - std::unique_ptr echo_detector; + rtc::scoped_refptr echo_detector; std::unique_ptr echo_controller; std::unique_ptr capture_post_processor; std::unique_ptr render_pre_processor; @@ -330,7 +330,7 @@ AudioProcessingBuilder& AudioProcessingBuilder::SetNonlinearBeamformer( } AudioProcessingBuilder& AudioProcessingBuilder::SetEchoDetector( - std::unique_ptr echo_detector) { + rtc::scoped_refptr echo_detector) { echo_detector_ = std::move(echo_detector); return *this; } @@ -363,7 +363,7 @@ AudioProcessingImpl::AudioProcessingImpl( std::unique_ptr capture_post_processor, std::unique_ptr render_pre_processor, std::unique_ptr echo_control_factory, - std::unique_ptr echo_detector, + rtc::scoped_refptr echo_detector, NonlinearBeamformer* beamformer) : data_dumper_( new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), @@ -422,7 +422,8 @@ AudioProcessingImpl::AudioProcessingImpl( // If no echo detector is injected, use the ResidualEchoDetector. if (!private_submodules_->echo_detector) { - private_submodules_->echo_detector.reset(new ResidualEchoDetector()); + private_submodules_->echo_detector = + new rtc::RefCountedObject(); } // TODO(alessiob): Move the injected gain controller once injection is diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h index 44b086bfd0..797498241b 100644 --- a/modules/audio_processing/audio_processing_impl.h +++ b/modules/audio_processing/audio_processing_impl.h @@ -44,7 +44,7 @@ class AudioProcessingImpl : public AudioProcessing { std::unique_ptr capture_post_processor, std::unique_ptr render_pre_processor, std::unique_ptr echo_control_factory, - std::unique_ptr echo_detector, + rtc::scoped_refptr echo_detector, NonlinearBeamformer* beamformer); ~AudioProcessingImpl() override; int Initialize() override; diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h index 6162199f04..ee419df46e 100644 --- a/modules/audio_processing/include/audio_processing.h +++ b/modules/audio_processing/include/audio_processing.h @@ -678,7 +678,7 @@ class AudioProcessingBuilder { std::unique_ptr nonlinear_beamformer); // The AudioProcessingBuilder takes ownership of the echo_detector. AudioProcessingBuilder& SetEchoDetector( - std::unique_ptr echo_detector); + rtc::scoped_refptr echo_detector); // This creates an APM instance using the previously set components. Calling // the Create function resets the AudioProcessingBuilder to its initial state. AudioProcessing* Create(); @@ -689,7 +689,7 @@ class AudioProcessingBuilder { std::unique_ptr capture_post_processing_; std::unique_ptr render_pre_processing_; std::unique_ptr nonlinear_beamformer_; - std::unique_ptr echo_detector_; + rtc::scoped_refptr echo_detector_; RTC_DISALLOW_COPY_AND_ASSIGN(AudioProcessingBuilder); }; @@ -1135,7 +1135,7 @@ class CustomProcessing { }; // Interface for an echo detector submodule. -class EchoDetector { +class EchoDetector : public rtc::RefCountInterface { public: // (Re-)Initializes the submodule. virtual void Initialize(int capture_sample_rate_hz, @@ -1161,8 +1161,6 @@ class EchoDetector { // Collect current metrics from the echo detector. virtual Metrics GetMetrics() const = 0; - - virtual ~EchoDetector() {} }; // The voice activity detection (VAD) component analyzes the stream to diff --git a/modules/audio_processing/residual_echo_detector_unittest.cc b/modules/audio_processing/residual_echo_detector_unittest.cc index 7bfa0d2eec..c6fb8e45c6 100644 --- a/modules/audio_processing/residual_echo_detector_unittest.cc +++ b/modules/audio_processing/residual_echo_detector_unittest.cc @@ -11,13 +11,15 @@ #include #include "modules/audio_processing/residual_echo_detector.h" +#include "rtc_base/refcountedobject.h" #include "test/gtest.h" namespace webrtc { TEST(ResidualEchoDetectorTests, Echo) { - ResidualEchoDetector echo_detector; - echo_detector.SetReliabilityForTest(1.0f); + rtc::scoped_refptr echo_detector = + new rtc::RefCountedObject(); + echo_detector->SetReliabilityForTest(1.0f); std::vector ones(160, 1.f); std::vector zeros(160, 0.f); @@ -26,24 +28,25 @@ TEST(ResidualEchoDetectorTests, Echo) { // frame interval. for (int i = 0; i < 1000; i++) { if (i % 20 == 0) { - echo_detector.AnalyzeRenderAudio(ones); - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeRenderAudio(ones); + echo_detector->AnalyzeCaptureAudio(zeros); } else if (i % 20 == 10) { - echo_detector.AnalyzeRenderAudio(zeros); - echo_detector.AnalyzeCaptureAudio(ones); + echo_detector->AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeCaptureAudio(ones); } else { - echo_detector.AnalyzeRenderAudio(zeros); - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeCaptureAudio(zeros); } } // We expect to detect echo with near certain likelihood. - auto ed_metrics = echo_detector.GetMetrics(); + auto ed_metrics = echo_detector->GetMetrics(); EXPECT_NEAR(1.f, ed_metrics.echo_likelihood, 0.01f); } TEST(ResidualEchoDetectorTests, NoEcho) { - ResidualEchoDetector echo_detector; - echo_detector.SetReliabilityForTest(1.0f); + rtc::scoped_refptr echo_detector = + new rtc::RefCountedObject(); + echo_detector->SetReliabilityForTest(1.0f); std::vector ones(160, 1.f); std::vector zeros(160, 0.f); @@ -51,20 +54,21 @@ TEST(ResidualEchoDetectorTests, NoEcho) { // detected. for (int i = 0; i < 1000; i++) { if (i % 20 == 0) { - echo_detector.AnalyzeRenderAudio(ones); + echo_detector->AnalyzeRenderAudio(ones); } else { - echo_detector.AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeRenderAudio(zeros); } - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeCaptureAudio(zeros); } // We expect to not detect any echo. - auto ed_metrics = echo_detector.GetMetrics(); + auto ed_metrics = echo_detector->GetMetrics(); EXPECT_NEAR(0.f, ed_metrics.echo_likelihood, 0.01f); } TEST(ResidualEchoDetectorTests, EchoWithRenderClockDrift) { - ResidualEchoDetector echo_detector; - echo_detector.SetReliabilityForTest(1.0f); + rtc::scoped_refptr echo_detector = + new rtc::RefCountedObject(); + echo_detector->SetReliabilityForTest(1.0f); std::vector ones(160, 1.f); std::vector zeros(160, 0.f); @@ -74,18 +78,18 @@ TEST(ResidualEchoDetectorTests, EchoWithRenderClockDrift) { // the render side producing data slightly faster. for (int i = 0; i < 1000; i++) { if (i % 20 == 0) { - echo_detector.AnalyzeRenderAudio(ones); - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeRenderAudio(ones); + echo_detector->AnalyzeCaptureAudio(zeros); } else if (i % 20 == 10) { - echo_detector.AnalyzeRenderAudio(zeros); - echo_detector.AnalyzeCaptureAudio(ones); + echo_detector->AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeCaptureAudio(ones); } else { - echo_detector.AnalyzeRenderAudio(zeros); - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeCaptureAudio(zeros); } if (i % 100 == 0) { // This is causing the simulated clock drift. - echo_detector.AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeRenderAudio(zeros); } } // We expect to detect echo with high likelihood. Clock drift is harder to @@ -94,13 +98,14 @@ TEST(ResidualEchoDetectorTests, EchoWithRenderClockDrift) { // A growing buffer can be caused by jitter or clock drift and it's not // possible to make this decision right away. For this reason we only expect // an echo likelihood of 75% in this test. - auto ed_metrics = echo_detector.GetMetrics(); + auto ed_metrics = echo_detector->GetMetrics(); EXPECT_GT(ed_metrics.echo_likelihood, 0.75f); } TEST(ResidualEchoDetectorTests, EchoWithCaptureClockDrift) { - ResidualEchoDetector echo_detector; - echo_detector.SetReliabilityForTest(1.0f); + rtc::scoped_refptr echo_detector = + new rtc::RefCountedObject(); + echo_detector->SetReliabilityForTest(1.0f); std::vector ones(160, 1.f); std::vector zeros(160, 0.f); @@ -110,22 +115,22 @@ TEST(ResidualEchoDetectorTests, EchoWithCaptureClockDrift) { // the capture side producing data slightly faster. for (int i = 0; i < 1000; i++) { if (i % 20 == 0) { - echo_detector.AnalyzeRenderAudio(ones); - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeRenderAudio(ones); + echo_detector->AnalyzeCaptureAudio(zeros); } else if (i % 20 == 10) { - echo_detector.AnalyzeRenderAudio(zeros); - echo_detector.AnalyzeCaptureAudio(ones); + echo_detector->AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeCaptureAudio(ones); } else { - echo_detector.AnalyzeRenderAudio(zeros); - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeRenderAudio(zeros); + echo_detector->AnalyzeCaptureAudio(zeros); } if (i % 100 == 0) { // This is causing the simulated clock drift. - echo_detector.AnalyzeCaptureAudio(zeros); + echo_detector->AnalyzeCaptureAudio(zeros); } } // We expect to detect echo with near certain likelihood. - auto ed_metrics = echo_detector.GetMetrics(); + auto ed_metrics = echo_detector->GetMetrics(); EXPECT_NEAR(1.f, ed_metrics.echo_likelihood, 0.01f); } diff --git a/test/fuzzers/residual_echo_detector_fuzzer.cc b/test/fuzzers/residual_echo_detector_fuzzer.cc index c3c81237c8..b0405ee9e1 100644 --- a/test/fuzzers/residual_echo_detector_fuzzer.cc +++ b/test/fuzzers/residual_echo_detector_fuzzer.cc @@ -17,6 +17,7 @@ #include "modules/audio_processing/residual_echo_detector.h" #include "rtc_base/checks.h" +#include "rtc_base/refcountedobject.h" namespace webrtc { @@ -42,10 +43,11 @@ void FuzzOneInput(const uint8_t* data, size_t size) { read_idx += 2; std::bitset<16> call_order(call_order_int); - ResidualEchoDetector echo_detector; + rtc::scoped_refptr echo_detector = + new rtc::RefCountedObject(); std::vector input(1); // Call AnalyzeCaptureAudio once to prevent the flushing of the buffer. - echo_detector.AnalyzeCaptureAudio(input); + echo_detector->AnalyzeCaptureAudio(input); for (size_t i = 0; i < 2 * kNrOfUpdates; ++i) { // Convert 4 input bytes to a float. RTC_DCHECK_LE(read_idx + sizeof(float), size); @@ -56,9 +58,9 @@ void FuzzOneInput(const uint8_t* data, size_t size) { continue; } if (call_order[i]) { - echo_detector.AnalyzeRenderAudio(input); + echo_detector->AnalyzeRenderAudio(input); } else { - echo_detector.AnalyzeCaptureAudio(input); + echo_detector->AnalyzeCaptureAudio(input); } } }