diff --git a/api/BUILD.gn b/api/BUILD.gn index aa5db9373c..8a76f2548b 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -124,6 +124,9 @@ rtc_source_set("mediastream_interface_and_implicit_video_frame_api") { sources = [ "mediastreaminterface.h", ] + deps = [ + "../modules/audio_processing:audio_processing_statistics", + ] } rtc_source_set("libjingle_api_deprecated_headers") { diff --git a/api/DEPS b/api/DEPS index 1e8e347924..a537633981 100644 --- a/api/DEPS +++ b/api/DEPS @@ -38,4 +38,9 @@ specific_include_rules = { ".*i420_buffer\.h": [ "+system_wrappers/include/aligned_malloc.h", ], + + # Needed to use the APM statistics. + "mediastreaminterface.h": [ + "+modules/audio_processing/include/audio_processing_statistics.h", + ], } diff --git a/api/mediastreaminterface.cc b/api/mediastreaminterface.cc index 92bca162af..4821da83b3 100644 --- a/api/mediastreaminterface.cc +++ b/api/mediastreaminterface.cc @@ -21,19 +21,18 @@ AudioProcessorInterface::GetStats(bool /*has_remote_tracks*/) { AudioProcessorStats stats; GetStats(&stats); AudioProcessorStatistics new_stats; - new_stats.aec_divergent_filter_fraction = - rtc::Optional(stats.aec_divergent_filter_fraction); - new_stats.aec_quality_min = rtc::Optional(stats.aec_quality_min); - new_stats.echo_delay_median_ms = - rtc::Optional(stats.echo_delay_median_ms); - new_stats.echo_delay_std_ms = rtc::Optional(stats.echo_delay_std_ms); - new_stats.echo_return_loss = rtc::Optional(stats.echo_return_loss); - new_stats.echo_return_loss_enhancement = - rtc::Optional(stats.echo_return_loss_enhancement); - new_stats.residual_echo_likelihood = - rtc::Optional(stats.residual_echo_likelihood); - new_stats.residual_echo_likelihood_recent_max = - rtc::Optional(stats.residual_echo_likelihood_recent_max); + new_stats.apm_statistics.divergent_filter_fraction = + stats.aec_divergent_filter_fraction; + new_stats.apm_statistics.delay_median_ms = stats.echo_delay_median_ms; + new_stats.apm_statistics.delay_standard_deviation_ms = + stats.echo_delay_std_ms; + new_stats.apm_statistics.echo_return_loss = stats.echo_return_loss; + new_stats.apm_statistics.echo_return_loss_enhancement = + stats.echo_return_loss_enhancement; + new_stats.apm_statistics.residual_echo_likelihood = + stats.residual_echo_likelihood; + new_stats.apm_statistics.residual_echo_likelihood_recent_max = + stats.residual_echo_likelihood_recent_max; return new_stats; } diff --git a/api/mediastreaminterface.h b/api/mediastreaminterface.h index 2cc5923d7e..80595e09ab 100644 --- a/api/mediastreaminterface.h +++ b/api/mediastreaminterface.h @@ -29,6 +29,7 @@ // mediachannel.h, which is no longer a dependency of this file. #include "media/base/videosinkinterface.h" #include "media/base/videosourceinterface.h" +#include "modules/audio_processing/include/audio_processing_statistics.h" #include "rtc_base/ratetracker.h" #include "rtc_base/refcount.h" #include "rtc_base/scoped_ref_ptr.h" @@ -255,14 +256,7 @@ class AudioProcessorInterface : public rtc::RefCountInterface { // regular stats struct when all users have been updated. struct AudioProcessorStatistics { bool typing_noise_detected = false; - rtc::Optional echo_return_loss; - rtc::Optional echo_return_loss_enhancement; - rtc::Optional echo_delay_median_ms; - rtc::Optional echo_delay_std_ms; - rtc::Optional aec_quality_min; - rtc::Optional residual_echo_likelihood; - rtc::Optional residual_echo_likelihood_recent_max; - rtc::Optional aec_divergent_filter_fraction; + AudioProcessingStats apm_statistics; }; // Get audio processor statistics. diff --git a/audio/BUILD.gn b/audio/BUILD.gn index 038338c03a..2a29ceb22b 100644 --- a/audio/BUILD.gn +++ b/audio/BUILD.gn @@ -102,6 +102,7 @@ if (rtc_include_tests) { "../call:rtp_receiver", "../modules/audio_device:mock_audio_device", "../modules/audio_mixer:audio_mixer_impl", + "../modules/audio_processing:audio_processing_statistics", "../modules/congestion_controller:congestion_controller", "../modules/congestion_controller:mock_congestion_controller", "../modules/pacing:mock_paced_sender", diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index 8583ed0e5f..2a5628cfa9 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -277,6 +277,11 @@ void AudioSendStream::SetMuted(bool muted) { } webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { + return GetStats(true); +} + +webrtc::AudioSendStream::Stats AudioSendStream::GetStats( + bool has_remote_tracks) const { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); webrtc::AudioSendStream::Stats stats; stats.local_ssrc = config_.rtp.ssrc; @@ -289,10 +294,6 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { if (call_stats.rttMs > 0) { stats.rtt_ms = call_stats.rttMs; } - // TODO(solenberg): [was ajm]: Re-enable this metric once we have a reliable - // implementation. - stats.aec_quality_min = -1; - if (config_.send_codec_spec) { const auto& spec = *config_.send_codec_spec; stats.codec_name = spec.format.name; @@ -323,23 +324,13 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { stats.total_input_energy = base->transmit_mixer()->GetTotalInputEnergy(); stats.total_input_duration = base->transmit_mixer()->GetTotalInputDuration(); - RTC_DCHECK(audio_state_->audio_processing()); - auto audio_processing_stats = - audio_state_->audio_processing()->GetStatistics(); - stats.echo_delay_median_ms = audio_processing_stats.delay_median; - stats.echo_delay_std_ms = audio_processing_stats.delay_standard_deviation; - stats.echo_return_loss = audio_processing_stats.echo_return_loss.instant(); - stats.echo_return_loss_enhancement = - audio_processing_stats.echo_return_loss_enhancement.instant(); - stats.residual_echo_likelihood = - audio_processing_stats.residual_echo_likelihood; - stats.residual_echo_likelihood_recent_max = - audio_processing_stats.residual_echo_likelihood_recent_max; - internal::AudioState* audio_state = static_cast(audio_state_.get()); stats.typing_noise_detected = audio_state->typing_noise_detected(); stats.ana_statistics = channel_proxy_->GetANAStatistics(); + RTC_DCHECK(audio_state_->audio_processing()); + stats.apm_statistics = + audio_state_->audio_processing()->GetStatistics(has_remote_tracks); return stats; } diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h index ef892691b9..08bdddb203 100644 --- a/audio/audio_send_stream.h +++ b/audio/audio_send_stream.h @@ -58,6 +58,8 @@ class AudioSendStream final : public webrtc::AudioSendStream, int duration_ms) override; void SetMuted(bool muted) override; webrtc::AudioSendStream::Stats GetStats() const override; + webrtc::AudioSendStream::Stats GetStats( + bool has_remote_tracks) const override; void SignalNetworkState(NetworkState state); bool DeliverRtcp(const uint8_t* packet, size_t length); diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc index c67eb9ba00..145a8e2419 100644 --- a/audio/audio_send_stream_unittest.cc +++ b/audio/audio_send_stream_unittest.cc @@ -19,6 +19,7 @@ #include "call/rtp_transport_controller_send_interface.h" #include "logging/rtc_event_log/mock/mock_rtc_event_log.h" #include "modules/audio_mixer/audio_mixer_impl.h" +#include "modules/audio_processing/include/audio_processing_statistics.h" #include "modules/audio_processing/include/mock_audio_processing.h" #include "modules/congestion_controller/include/mock/mock_congestion_observer.h" #include "modules/congestion_controller/include/send_side_congestion_controller.h" @@ -50,11 +51,13 @@ const uint32_t kSsrc = 1234; const char* kCName = "foo_name"; const int kAudioLevelId = 2; const int kTransportSequenceNumberId = 4; -const int kEchoDelayMedian = 254; -const int kEchoDelayStdDev = -3; -const int kEchoReturnLoss = -65; -const int kEchoReturnLossEnhancement = 101; -const float kResidualEchoLikelihood = -1.0f; +const int32_t kEchoDelayMedian = 254; +const int32_t kEchoDelayStdDev = -3; +const double kDivergentFilterFraction = 0.2f; +const double kEchoReturnLoss = -65; +const double kEchoReturnLossEnhancement = 101; +const double kResidualEchoLikelihood = -1.0f; +const double kResidualEchoLikelihoodMax = 23.0f; const int32_t kSpeechInputLevel = 96; const double kTotalInputEnergy = 0.25; const double kTotalInputDuration = 0.5; @@ -310,17 +313,18 @@ struct ConfigHelper { EXPECT_CALL(transmit_mixer_, typing_noise_detected()) .WillRepeatedly(Return(true)); - // We have to set the instantaneous value, the average, min and max. We only - // care about the instantaneous value, so we set all to the same value. - audio_processing_stats_.echo_return_loss.Set( - kEchoReturnLoss, kEchoReturnLoss, kEchoReturnLoss, kEchoReturnLoss); - audio_processing_stats_.echo_return_loss_enhancement.Set( - kEchoReturnLossEnhancement, kEchoReturnLossEnhancement, - kEchoReturnLossEnhancement, kEchoReturnLossEnhancement); - audio_processing_stats_.delay_median = kEchoDelayMedian; - audio_processing_stats_.delay_standard_deviation = kEchoDelayStdDev; + audio_processing_stats_.echo_return_loss = kEchoReturnLoss; + audio_processing_stats_.echo_return_loss_enhancement = + kEchoReturnLossEnhancement; + audio_processing_stats_.delay_median_ms = kEchoDelayMedian; + audio_processing_stats_.delay_standard_deviation_ms = kEchoDelayStdDev; + audio_processing_stats_.divergent_filter_fraction = + kDivergentFilterFraction; + audio_processing_stats_.residual_echo_likelihood = kResidualEchoLikelihood; + audio_processing_stats_.residual_echo_likelihood_recent_max = + kResidualEchoLikelihoodMax; - EXPECT_CALL(*audio_processing_, GetStatistics()) + EXPECT_CALL(*audio_processing_, GetStatistics(true)) .WillRepeatedly(Return(audio_processing_stats_)); } @@ -331,7 +335,7 @@ struct ConfigHelper { testing::StrictMock* channel_proxy_ = nullptr; rtc::scoped_refptr audio_processing_; MockTransmitMixer transmit_mixer_; - AudioProcessing::AudioProcessingStatistics audio_processing_stats_; + AudioProcessingStats audio_processing_stats_; SimulatedClock simulated_clock_; PacketRouter packet_router_; testing::NiceMock pacer_; @@ -429,7 +433,7 @@ TEST(AudioSendStreamTest, GetStats) { helper.transport(), helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats(), rtc::nullopt); helper.SetupMockForGetStats(); - AudioSendStream::Stats stats = send_stream.GetStats(); + AudioSendStream::Stats stats = send_stream.GetStats(true); EXPECT_EQ(kSsrc, stats.local_ssrc); EXPECT_EQ(static_cast(kCallStats.bytesSent), stats.bytes_sent); EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent); @@ -446,12 +450,17 @@ TEST(AudioSendStreamTest, GetStats) { EXPECT_EQ(static_cast(kSpeechInputLevel), stats.audio_level); EXPECT_EQ(kTotalInputEnergy, stats.total_input_energy); EXPECT_EQ(kTotalInputDuration, stats.total_input_duration); - EXPECT_EQ(-1, stats.aec_quality_min); - EXPECT_EQ(kEchoDelayMedian, stats.echo_delay_median_ms); - EXPECT_EQ(kEchoDelayStdDev, stats.echo_delay_std_ms); - EXPECT_EQ(kEchoReturnLoss, stats.echo_return_loss); - EXPECT_EQ(kEchoReturnLossEnhancement, stats.echo_return_loss_enhancement); - EXPECT_EQ(kResidualEchoLikelihood, stats.residual_echo_likelihood); + EXPECT_EQ(kEchoDelayMedian, stats.apm_statistics.delay_median_ms); + EXPECT_EQ(kEchoDelayStdDev, stats.apm_statistics.delay_standard_deviation_ms); + EXPECT_EQ(kEchoReturnLoss, stats.apm_statistics.echo_return_loss); + EXPECT_EQ(kEchoReturnLossEnhancement, + stats.apm_statistics.echo_return_loss_enhancement); + EXPECT_EQ(kDivergentFilterFraction, + stats.apm_statistics.divergent_filter_fraction); + EXPECT_EQ(kResidualEchoLikelihood, + stats.apm_statistics.residual_echo_likelihood); + EXPECT_EQ(kResidualEchoLikelihoodMax, + stats.apm_statistics.residual_echo_likelihood_recent_max); EXPECT_TRUE(stats.typing_noise_detected); } diff --git a/audio/test/audio_stats_test.cc b/audio/test/audio_stats_test.cc index a1fecb8298..ee225c0b50 100644 --- a/audio/test/audio_stats_test.cc +++ b/audio/test/audio_stats_test.cc @@ -57,13 +57,12 @@ class NoLossTest : public AudioEndToEndTest { EXPECT_EQ(0, send_stats.audio_level); // send_stats.total_input_energy // send_stats.total_input_duration - EXPECT_EQ(-1.0f, send_stats.aec_quality_min); - EXPECT_EQ(-1, send_stats.echo_delay_median_ms); - EXPECT_EQ(-1, send_stats.echo_delay_std_ms); - EXPECT_EQ(-100, send_stats.echo_return_loss); - EXPECT_EQ(-100, send_stats.echo_return_loss_enhancement); - EXPECT_EQ(0.0f, send_stats.residual_echo_likelihood); - EXPECT_EQ(0.0f, send_stats.residual_echo_likelihood_recent_max); + EXPECT_FALSE(send_stats.apm_statistics.delay_median_ms); + EXPECT_FALSE(send_stats.apm_statistics.delay_standard_deviation_ms); + EXPECT_FALSE(send_stats.apm_statistics.echo_return_loss); + EXPECT_FALSE(send_stats.apm_statistics.echo_return_loss_enhancement); + EXPECT_FALSE(send_stats.apm_statistics.residual_echo_likelihood); + EXPECT_FALSE(send_stats.apm_statistics.residual_echo_likelihood_recent_max); EXPECT_EQ(false, send_stats.typing_noise_detected); AudioReceiveStream::Stats recv_stats = receive_stream()->GetStats(); diff --git a/call/BUILD.gn b/call/BUILD.gn index 3c834f105b..740450466a 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -29,6 +29,7 @@ rtc_source_set("call_interfaces") { "../api:optional", "../api:transport_api", "../api/audio_codecs:audio_codecs_api", + "../modules/audio_processing:audio_processing_statistics", "../rtc_base:rtc_base", "../rtc_base:rtc_base_approved", ] diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h index 9ed0d1e63f..4912182c12 100644 --- a/call/audio_send_stream.h +++ b/call/audio_send_stream.h @@ -22,6 +22,7 @@ #include "api/optional.h" #include "api/rtpparameters.h" #include "call/rtp_config.h" +#include "modules/audio_processing/include/audio_processing_statistics.h" #include "rtc_base/scoped_ref_ptr.h" #include "typedefs.h" // NOLINT(build/include) @@ -54,15 +55,10 @@ class AudioSendStream { // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy double total_input_energy = 0.0; double total_input_duration = 0.0; - float aec_quality_min = -1.0f; - int32_t echo_delay_median_ms = -1; - int32_t echo_delay_std_ms = -1; - int32_t echo_return_loss = -100; - int32_t echo_return_loss_enhancement = -100; - float residual_echo_likelihood = -1.0f; - float residual_echo_likelihood_recent_max = -1.0f; bool typing_noise_detected = false; + ANAStats ana_statistics; + AudioProcessingStats apm_statistics; }; struct Config { @@ -157,6 +153,7 @@ class AudioSendStream { virtual void SetMuted(bool muted) = 0; virtual Stats GetStats() const = 0; + virtual Stats GetStats(bool has_remote_tracks) const = 0; }; } // namespace webrtc diff --git a/media/base/mediachannel.h b/media/base/mediachannel.h index 0b84ff79cc..7306ebf430 100644 --- a/media/base/mediachannel.h +++ b/media/base/mediachannel.h @@ -27,6 +27,7 @@ #include "media/base/streamparams.h" #include "media/base/videosinkinterface.h" #include "media/base/videosourceinterface.h" +#include "modules/audio_processing/include/audio_processing_statistics.h" #include "rtc_base/basictypes.h" #include "rtc_base/buffer.h" #include "rtc_base/copyonwritebuffer.h" @@ -624,6 +625,8 @@ struct VoiceSenderInfo : public MediaSenderInfo { // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy double total_input_energy; double total_input_duration; + // TODO(bugs.webrtc.org/8572): Remove APM stats from this struct, since they + // are no longer needed now that we have apm_statistics. float aec_quality_min; int echo_delay_median_ms; int echo_delay_std_ms; @@ -633,6 +636,7 @@ struct VoiceSenderInfo : public MediaSenderInfo { float residual_echo_likelihood_recent_max; bool typing_noise_detected; webrtc::ANAStats ana_statistics; + webrtc::AudioProcessingStats apm_statistics; }; struct VoiceReceiverInfo : public MediaReceiverInfo { diff --git a/media/engine/fakewebrtccall.cc b/media/engine/fakewebrtccall.cc index 9c266bc572..3d95e511e6 100644 --- a/media/engine/fakewebrtccall.cc +++ b/media/engine/fakewebrtccall.cc @@ -64,6 +64,11 @@ webrtc::AudioSendStream::Stats FakeAudioSendStream::GetStats() const { return stats_; } +webrtc::AudioSendStream::Stats FakeAudioSendStream::GetStats( + bool /*has_remote_tracks*/) const { + return stats_; +} + FakeAudioReceiveStream::FakeAudioReceiveStream( int id, const webrtc::AudioReceiveStream::Config& config) : id_(id), config_(config) { diff --git a/media/engine/fakewebrtccall.h b/media/engine/fakewebrtccall.h index 3d0825d237..e598e9014a 100644 --- a/media/engine/fakewebrtccall.h +++ b/media/engine/fakewebrtccall.h @@ -65,6 +65,8 @@ class FakeAudioSendStream final : public webrtc::AudioSendStream { int duration_ms) override; void SetMuted(bool muted) override; webrtc::AudioSendStream::Stats GetStats() const override; + webrtc::AudioSendStream::Stats GetStats( + bool has_remote_tracks) const override; int id_ = -1; TelephoneEvent latest_telephone_event_; diff --git a/media/engine/webrtcvoiceengine.cc b/media/engine/webrtcvoiceengine.cc index 808c5d2d1d..0ae975dce0 100644 --- a/media/engine/webrtcvoiceengine.cc +++ b/media/engine/webrtcvoiceengine.cc @@ -923,10 +923,10 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream return muted_; } - webrtc::AudioSendStream::Stats GetStats() const { + webrtc::AudioSendStream::Stats GetStats(bool has_remote_tracks) const { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); RTC_DCHECK(stream_); - return stream_->GetStats(); + return stream_->GetStats(has_remote_tracks); } // Starts the sending by setting ourselves as a sink to the AudioSource to @@ -2200,7 +2200,8 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { // Get SSRC and stats for each sender. RTC_DCHECK_EQ(info->senders.size(), 0U); for (const auto& stream : send_streams_) { - webrtc::AudioSendStream::Stats stats = stream.second->GetStats(); + webrtc::AudioSendStream::Stats stats = + stream.second->GetStats(recv_streams_.size() > 0); VoiceSenderInfo sinfo; sinfo.add_ssrc(stats.local_ssrc); sinfo.bytes_sent = stats.bytes_sent; @@ -2215,16 +2216,9 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { sinfo.audio_level = stats.audio_level; sinfo.total_input_energy = stats.total_input_energy; sinfo.total_input_duration = stats.total_input_duration; - sinfo.aec_quality_min = stats.aec_quality_min; - sinfo.echo_delay_median_ms = stats.echo_delay_median_ms; - sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; - sinfo.echo_return_loss = stats.echo_return_loss; - sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; - sinfo.residual_echo_likelihood = stats.residual_echo_likelihood; - sinfo.residual_echo_likelihood_recent_max = - stats.residual_echo_likelihood_recent_max; sinfo.typing_noise_detected = (send_ ? stats.typing_noise_detected : false); sinfo.ana_statistics = stats.ana_statistics; + sinfo.apm_statistics = stats.apm_statistics; info->senders.push_back(sinfo); } diff --git a/media/engine/webrtcvoiceengine_unittest.cc b/media/engine/webrtcvoiceengine_unittest.cc index b03c8df5b8..0a165f5748 100644 --- a/media/engine/webrtcvoiceengine_unittest.cc +++ b/media/engine/webrtcvoiceengine_unittest.cc @@ -557,13 +557,12 @@ class WebRtcVoiceEngineTestFake : public testing::Test { stats.jitter_ms = 12; stats.rtt_ms = 345; stats.audio_level = 678; - stats.aec_quality_min = 9.01f; - stats.echo_delay_median_ms = 234; - stats.echo_delay_std_ms = 567; - stats.echo_return_loss = 890; - stats.echo_return_loss_enhancement = 1234; - stats.residual_echo_likelihood = 0.432f; - stats.residual_echo_likelihood_recent_max = 0.6f; + stats.apm_statistics.delay_median_ms = 234; + stats.apm_statistics.delay_standard_deviation_ms = 567; + stats.apm_statistics.echo_return_loss = 890; + stats.apm_statistics.echo_return_loss_enhancement = 1234; + stats.apm_statistics.residual_echo_likelihood = 0.432f; + stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f; stats.ana_statistics.bitrate_action_counter = 321; stats.ana_statistics.channel_action_counter = 432; stats.ana_statistics.dtx_action_counter = 543; @@ -593,15 +592,18 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_EQ(info.jitter_ms, stats.jitter_ms); EXPECT_EQ(info.rtt_ms, stats.rtt_ms); EXPECT_EQ(info.audio_level, stats.audio_level); - EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min); - EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms); - EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms); - EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss); - EXPECT_EQ(info.echo_return_loss_enhancement, - stats.echo_return_loss_enhancement); - EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood); - EXPECT_EQ(info.residual_echo_likelihood_recent_max, - stats.residual_echo_likelihood_recent_max); + EXPECT_EQ(info.apm_statistics.delay_median_ms, + stats.apm_statistics.delay_median_ms); + EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms, + stats.apm_statistics.delay_standard_deviation_ms); + EXPECT_EQ(info.apm_statistics.echo_return_loss, + stats.apm_statistics.echo_return_loss); + EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement, + stats.apm_statistics.echo_return_loss_enhancement); + EXPECT_EQ(info.apm_statistics.residual_echo_likelihood, + stats.apm_statistics.residual_echo_likelihood); + EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max, + stats.apm_statistics.residual_echo_likelihood_recent_max); EXPECT_EQ(info.ana_statistics.bitrate_action_counter, stats.ana_statistics.bitrate_action_counter); EXPECT_EQ(info.ana_statistics.channel_action_counter, diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index fa3f3bdee4..fdc4783edf 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -233,6 +233,7 @@ rtc_static_library("audio_processing") { defines = [] deps = [ ":aec_dump_interface", + ":audio_processing_statistics", "..:module_api", "../..:webrtc_common", "../../api:array_view", @@ -311,6 +312,16 @@ rtc_static_library("audio_processing") { ] } +rtc_source_set("audio_processing_statistics") { + sources = [ + "include/audio_processing_statistics.cc", + "include/audio_processing_statistics.h", + ] + deps = [ + "../../api:optional", + ] +} + rtc_source_set("aec_dump_interface") { sources = [ "include/aec_dump.cc", diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 4a39bb9deb..b5ef42e5dc 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -1557,13 +1557,6 @@ AudioProcessing::AudioProcessingStatistics::AudioProcessingStatistics( AudioProcessing::AudioProcessingStatistics::~AudioProcessingStatistics() = default; -AudioProcessing::AudioProcessingStats::AudioProcessingStats() = default; - -AudioProcessing::AudioProcessingStats::AudioProcessingStats( - const AudioProcessingStats& other) = default; - -AudioProcessing::AudioProcessingStats::~AudioProcessingStats() = default; - // TODO(ivoc): Remove this when GetStatistics() becomes pure virtual. AudioProcessing::AudioProcessingStatistics AudioProcessing::GetStatistics() const { @@ -1571,7 +1564,7 @@ AudioProcessing::AudioProcessingStatistics AudioProcessing::GetStatistics() } // TODO(ivoc): Remove this when GetStatistics() becomes pure virtual. -AudioProcessing::AudioProcessingStats AudioProcessing::GetStatistics( +AudioProcessingStats AudioProcessing::GetStatistics( bool has_remote_tracks) const { return AudioProcessingStats(); } @@ -1611,7 +1604,7 @@ AudioProcessing::AudioProcessingStatistics AudioProcessingImpl::GetStatistics() return stats; } -AudioProcessing::AudioProcessingStats AudioProcessingImpl::GetStatistics( +AudioProcessingStats AudioProcessingImpl::GetStatistics( bool has_remote_tracks) const { AudioProcessingStats stats; if (has_remote_tracks) { diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc index c3402dd500..4da0621abf 100644 --- a/modules/audio_processing/audio_processing_unittest.cc +++ b/modules/audio_processing/audio_processing_unittest.cc @@ -3026,7 +3026,7 @@ TEST(MAYBE_ApmStatistics, AEC2EnabledTest) { } // Test statistics interface. - AudioProcessing::AudioProcessingStats stats = apm->GetStatistics(true); + AudioProcessingStats stats = apm->GetStatistics(true); // We expect all statistics to be set and have a sensible value. ASSERT_TRUE(stats.residual_echo_likelihood); EXPECT_GE(*stats.residual_echo_likelihood, 0.0); @@ -3085,7 +3085,7 @@ TEST(MAYBE_ApmStatistics, AECMEnabledTest) { } // Test statistics interface. - AudioProcessing::AudioProcessingStats stats = apm->GetStatistics(true); + AudioProcessingStats stats = apm->GetStatistics(true); // We expect only the residual echo detector statistics to be set and have a // sensible value. EXPECT_TRUE(stats.residual_echo_likelihood); diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h index a4245c6b34..6c8f4dbc02 100644 --- a/modules/audio_processing/include/audio_processing.h +++ b/modules/audio_processing/include/audio_processing.h @@ -22,6 +22,7 @@ #include "api/optional.h" #include "modules/audio_processing/beamformer/array_util.h" +#include "modules/audio_processing/include/audio_processing_statistics.h" #include "modules/audio_processing/include/config.h" #include "rtc_base/arraysize.h" #include "rtc_base/deprecation.h" @@ -564,38 +565,6 @@ class AudioProcessing : public rtc::RefCountInterface { float residual_echo_likelihood_recent_max = -1.0f; }; - // This version of the stats uses Optionals, it will replace the regular - // AudioProcessingStatistics struct. - struct AudioProcessingStats { - AudioProcessingStats(); - AudioProcessingStats(const AudioProcessingStats& other); - ~AudioProcessingStats(); - - // AEC Statistics. - // ERL = 10log_10(P_far / P_echo) - rtc::Optional echo_return_loss; - // ERLE = 10log_10(P_echo / P_out) - rtc::Optional echo_return_loss_enhancement; - // Fraction of time that the AEC linear filter is divergent, in a 1-second - // non-overlapped aggregation window. - rtc::Optional divergent_filter_fraction; - - // The delay metrics consists of the delay median and standard deviation. It - // also consists of the fraction of delay estimates that can make the echo - // cancellation perform poorly. The values are aggregated until the first - // call to |GetStatistics()| and afterwards aggregated and updated every - // second. Note that if there are several clients pulling metrics from - // |GetStatistics()| during a session the first call from any of them will - // change to one second aggregation window for all. - rtc::Optional delay_median_ms; - rtc::Optional delay_standard_deviation_ms; - - // Residual echo detector likelihood. - rtc::Optional residual_echo_likelihood; - // Maximum residual echo likelihood from the last time period. - rtc::Optional residual_echo_likelihood_recent_max; - }; - // TODO(ivoc): Make this pure virtual when all subclasses have been updated. virtual AudioProcessingStatistics GetStatistics() const; diff --git a/modules/audio_processing/include/audio_processing_statistics.cc b/modules/audio_processing/include/audio_processing_statistics.cc new file mode 100644 index 0000000000..7139ee502e --- /dev/null +++ b/modules/audio_processing/include/audio_processing_statistics.cc @@ -0,0 +1,22 @@ +/* + * Copyright 2017 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 "modules/audio_processing/include/audio_processing_statistics.h" + +namespace webrtc { + +AudioProcessingStats::AudioProcessingStats() = default; + +AudioProcessingStats::AudioProcessingStats(const AudioProcessingStats& other) = + default; + +AudioProcessingStats::~AudioProcessingStats() = default; + +} // namespace webrtc diff --git a/modules/audio_processing/include/audio_processing_statistics.h b/modules/audio_processing/include/audio_processing_statistics.h new file mode 100644 index 0000000000..7dbc90735a --- /dev/null +++ b/modules/audio_processing/include/audio_processing_statistics.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 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 MODULES_AUDIO_PROCESSING_INCLUDE_AUDIO_PROCESSING_STATISTICS_H_ +#define MODULES_AUDIO_PROCESSING_INCLUDE_AUDIO_PROCESSING_STATISTICS_H_ + +#include "api/optional.h" + +namespace webrtc { +// This version of the stats uses Optionals, it will replace the regular +// AudioProcessingStatistics struct. +struct AudioProcessingStats { + AudioProcessingStats(); + AudioProcessingStats(const AudioProcessingStats& other); + ~AudioProcessingStats(); + + // AEC Statistics. + // ERL = 10log_10(P_far / P_echo) + rtc::Optional echo_return_loss; + // ERLE = 10log_10(P_echo / P_out) + rtc::Optional echo_return_loss_enhancement; + // Fraction of time that the AEC linear filter is divergent, in a 1-second + // non-overlapped aggregation window. + rtc::Optional divergent_filter_fraction; + + // The delay metrics consists of the delay median and standard deviation. It + // also consists of the fraction of delay estimates that can make the echo + // cancellation perform poorly. The values are aggregated until the first + // call to |GetStatistics()| and afterwards aggregated and updated every + // second. Note that if there are several clients pulling metrics from + // |GetStatistics()| during a session the first call from any of them will + // change to one second aggregation window for all. + rtc::Optional delay_median_ms; + rtc::Optional delay_standard_deviation_ms; + + // Residual echo detector likelihood. + rtc::Optional residual_echo_likelihood; + // Maximum residual echo likelihood from the last time period. + rtc::Optional residual_echo_likelihood_recent_max; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_INCLUDE_AUDIO_PROCESSING_STATISTICS_H_ diff --git a/modules/audio_processing/include/mock_audio_processing.h b/modules/audio_processing/include/mock_audio_processing.h index 7cbd166d01..f2bdc2f241 100644 --- a/modules/audio_processing/include/mock_audio_processing.h +++ b/modules/audio_processing/include/mock_audio_processing.h @@ -15,6 +15,7 @@ #include "modules/audio_processing/include/aec_dump.h" #include "modules/audio_processing/include/audio_processing.h" +#include "modules/audio_processing/include/audio_processing_statistics.h" #include "test/gmock.h" namespace webrtc { @@ -199,6 +200,7 @@ class MockAudioProcessing : public AudioProcessing { MOCK_METHOD0(UpdateHistogramsOnCallEnd, void()); MOCK_CONST_METHOD0(GetStatistics, AudioProcessingStatistics()); + MOCK_CONST_METHOD1(GetStatistics, AudioProcessingStats(bool)); virtual MockEchoCancellation* echo_cancellation() const { return echo_cancellation_.get(); } diff --git a/pc/rtcstatscollector.cc b/pc/rtcstatscollector.cc index a23ab30185..aa901796bf 100644 --- a/pc/rtcstatscollector.cc +++ b/pc/rtcstatscollector.cc @@ -404,13 +404,13 @@ ProduceMediaStreamTrackStatsFromVoiceSenderInfo( audio_track_stats->total_audio_energy = voice_sender_info.total_input_energy; audio_track_stats->total_samples_duration = voice_sender_info.total_input_duration; - if (voice_sender_info.echo_return_loss != -100) { - audio_track_stats->echo_return_loss = static_cast( - voice_sender_info.echo_return_loss); + if (voice_sender_info.apm_statistics.echo_return_loss) { + audio_track_stats->echo_return_loss = + *voice_sender_info.apm_statistics.echo_return_loss; } - if (voice_sender_info.echo_return_loss_enhancement != -100) { - audio_track_stats->echo_return_loss_enhancement = static_cast( - voice_sender_info.echo_return_loss_enhancement); + if (voice_sender_info.apm_statistics.echo_return_loss_enhancement) { + audio_track_stats->echo_return_loss_enhancement = + *voice_sender_info.apm_statistics.echo_return_loss_enhancement; } return audio_track_stats; } diff --git a/pc/rtcstatscollector_unittest.cc b/pc/rtcstatscollector_unittest.cc index d6c21cebfa..413b13b616 100644 --- a/pc/rtcstatscollector_unittest.cc +++ b/pc/rtcstatscollector_unittest.cc @@ -1516,8 +1516,8 @@ TEST_F(RTCStatsCollectorTest, voice_sender_info_ssrc1.audio_level = 32767; voice_sender_info_ssrc1.total_input_energy = 0.25; voice_sender_info_ssrc1.total_input_duration = 0.5; - voice_sender_info_ssrc1.echo_return_loss = 42; - voice_sender_info_ssrc1.echo_return_loss_enhancement = 52; + voice_sender_info_ssrc1.apm_statistics.echo_return_loss = 42.0; + voice_sender_info_ssrc1.apm_statistics.echo_return_loss_enhancement = 52.0; // Uses default values, the corresponding stats object should contain // undefined members. @@ -1527,8 +1527,6 @@ TEST_F(RTCStatsCollectorTest, voice_sender_info_ssrc2.audio_level = 0; voice_sender_info_ssrc2.total_input_energy = 0.0; voice_sender_info_ssrc2.total_input_duration = 0.0; - voice_sender_info_ssrc2.echo_return_loss = -100; - voice_sender_info_ssrc2.echo_return_loss_enhancement = -100; // Remote audio track rtc::scoped_refptr remote_audio_track = diff --git a/pc/statscollector.cc b/pc/statscollector.cc index 6b27dfd290..0344c988fa 100644 --- a/pc/statscollector.cc +++ b/pc/statscollector.cc @@ -99,50 +99,39 @@ void ExtractCommonReceiveProperties(const cricket::MediaReceiverInfo& info, report->AddString(StatsReport::kStatsValueNameCodecName, info.codec_name); } -void SetAudioProcessingStats( - StatsReport* report, - bool typing_noise_detected, - rtc::Optional echo_return_loss, - rtc::Optional echo_return_loss_enhancement, - rtc::Optional echo_delay_median_ms, - rtc::Optional aec_quality_min, - rtc::Optional echo_delay_std_ms, - rtc::Optional residual_echo_likelihood, - rtc::Optional residual_echo_likelihood_recent_max) { +void SetAudioProcessingStats(StatsReport* report, + bool typing_noise_detected, + const AudioProcessingStats& apm_stats) { report->AddBoolean(StatsReport::kStatsValueNameTypingNoiseState, typing_noise_detected); - // TODO(ivoc): Remove the checks for default values once the whole stat - // chain uses optionals. - if (aec_quality_min && *aec_quality_min >= 0.0) { - report->AddFloat(StatsReport::kStatsValueNameEchoCancellationQualityMin, - *aec_quality_min); - } - if (echo_delay_median_ms && *echo_delay_median_ms >= 0) { + if (apm_stats.delay_median_ms) { report->AddInt(StatsReport::kStatsValueNameEchoDelayMedian, - *echo_delay_median_ms); + *apm_stats.delay_median_ms); } - if (echo_delay_std_ms && *echo_delay_std_ms >= 0) { + if (apm_stats.delay_standard_deviation_ms) { report->AddInt(StatsReport::kStatsValueNameEchoDelayStdDev, - *echo_delay_std_ms); + *apm_stats.delay_standard_deviation_ms); } - // These can take on valid negative values. - if (echo_return_loss) { + if (apm_stats.echo_return_loss) { report->AddInt(StatsReport::kStatsValueNameEchoReturnLoss, - static_cast(*echo_return_loss)); + *apm_stats.echo_return_loss); } - if (echo_return_loss_enhancement) { + if (apm_stats.echo_return_loss_enhancement) { report->AddInt(StatsReport::kStatsValueNameEchoReturnLossEnhancement, - static_cast(*echo_return_loss_enhancement)); + *apm_stats.echo_return_loss_enhancement); } - if (residual_echo_likelihood && *residual_echo_likelihood >= 0.0) { + if (apm_stats.residual_echo_likelihood) { report->AddFloat(StatsReport::kStatsValueNameResidualEchoLikelihood, - *residual_echo_likelihood); + static_cast(*apm_stats.residual_echo_likelihood)); } - if (residual_echo_likelihood_recent_max && - *residual_echo_likelihood_recent_max >= 0.0) { + if (apm_stats.residual_echo_likelihood_recent_max) { report->AddFloat( StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax, - *residual_echo_likelihood_recent_max); + static_cast(*apm_stats.residual_echo_likelihood_recent_max)); + } + if (apm_stats.divergent_filter_fraction) { + report->AddFloat(StatsReport::kStatsValueNameAecDivergentFilterFraction, + static_cast(*apm_stats.divergent_filter_fraction)); } } @@ -204,16 +193,8 @@ void ExtractStats(const cricket::VoiceReceiverInfo& info, StatsReport* report) { void ExtractStats(const cricket::VoiceSenderInfo& info, StatsReport* report) { ExtractCommonSendProperties(info, report); - // TODO(ivoc): Update VoiceSenderInfo to pass Optionals all the way from APM. - SetAudioProcessingStats( - report, info.typing_noise_detected, - rtc::Optional(info.echo_return_loss), - rtc::Optional(info.echo_return_loss_enhancement), - rtc::Optional(info.echo_delay_median_ms), - rtc::Optional(info.aec_quality_min), - rtc::Optional(info.echo_delay_std_ms), - rtc::Optional(info.residual_echo_likelihood), - rtc::Optional(info.residual_echo_likelihood_recent_max)); + SetAudioProcessingStats(report, info.typing_noise_detected, + info.apm_statistics); const FloatForAdd floats[] = { { StatsReport::kStatsValueNameTotalAudioEnergy, info.total_input_energy }, @@ -1033,17 +1014,8 @@ void StatsCollector::UpdateReportFromAudioTrack(AudioTrackInterface* track, AudioProcessorInterface::AudioProcessorStatistics stats = audio_processor->GetStats(has_remote_tracks); - SetAudioProcessingStats( - report, stats.typing_noise_detected, stats.echo_return_loss, - stats.echo_return_loss_enhancement, stats.echo_delay_median_ms, - stats.aec_quality_min, stats.echo_delay_std_ms, - stats.residual_echo_likelihood, - stats.residual_echo_likelihood_recent_max); - - if (stats.aec_divergent_filter_fraction) { - report->AddFloat(StatsReport::kStatsValueNameAecDivergentFilterFraction, - *stats.aec_divergent_filter_fraction); - } + SetAudioProcessingStats(report, stats.typing_noise_detected, + stats.apm_statistics); } } diff --git a/pc/statscollector_unittest.cc b/pc/statscollector_unittest.cc index d65e3a61c0..ffae504e88 100644 --- a/pc/statscollector_unittest.cc +++ b/pc/statscollector_unittest.cc @@ -84,19 +84,19 @@ class FakeAudioProcessor : public webrtc::AudioProcessorInterface { stats->echo_return_loss = 2; stats->echo_return_loss_enhancement = 3; stats->echo_delay_median_ms = 4; - stats->aec_quality_min = 5.1f; stats->echo_delay_std_ms = 6; } AudioProcessorInterface::AudioProcessorStatistics GetStats( - bool /*has_recv_streams*/) override { + bool has_recv_streams) override { AudioProcessorStatistics stats; stats.typing_noise_detected = true; - stats.echo_return_loss = rtc::Optional(2.0); - stats.echo_return_loss_enhancement = rtc::Optional(3.0); - stats.echo_delay_median_ms = rtc::Optional(4); - stats.aec_quality_min = rtc::Optional(5.1); - stats.echo_delay_std_ms = rtc::Optional(6); + if (has_recv_streams) { + stats.apm_statistics.echo_return_loss = 2.0; + stats.apm_statistics.echo_return_loss_enhancement = 3.0; + stats.apm_statistics.delay_median_ms = 4; + stats.apm_statistics.delay_standard_deviation_ms = 5; + } return stats; } }; @@ -137,7 +137,6 @@ class FakeAudioProcessorWithInitValue : public webrtc::AudioProcessorInterface { stats->echo_return_loss = -100; stats->echo_return_loss_enhancement = -100; stats->echo_delay_median_ms = -1; - stats->aec_quality_min = -1.0f; stats->echo_delay_std_ms = -1; } @@ -409,37 +408,70 @@ void VerifyVoiceSenderInfoReport(const StatsReport* report, EXPECT_TRUE(GetValue( report, StatsReport::kStatsValueNameJitterReceived, &value_in_report)); EXPECT_EQ(rtc::ToString(sinfo.jitter_ms), value_in_report); - EXPECT_TRUE(GetValue( - report, StatsReport::kStatsValueNameEchoCancellationQualityMin, - &value_in_report)); - EXPECT_EQ(rtc::ToString(sinfo.aec_quality_min), value_in_report); - EXPECT_TRUE(GetValue( - report, StatsReport::kStatsValueNameEchoDelayMedian, &value_in_report)); - EXPECT_EQ(rtc::ToString(sinfo.echo_delay_median_ms), - value_in_report); - EXPECT_TRUE(GetValue( - report, StatsReport::kStatsValueNameEchoDelayStdDev, &value_in_report)); - EXPECT_EQ(rtc::ToString(sinfo.echo_delay_std_ms), - value_in_report); - EXPECT_TRUE(GetValue( - report, StatsReport::kStatsValueNameEchoReturnLoss, &value_in_report)); - EXPECT_EQ(rtc::ToString(sinfo.echo_return_loss), - value_in_report); - EXPECT_TRUE(GetValue( - report, StatsReport::kStatsValueNameEchoReturnLossEnhancement, - &value_in_report)); - EXPECT_EQ(rtc::ToString(sinfo.echo_return_loss_enhancement), - value_in_report); - EXPECT_TRUE(GetValue(report, - StatsReport::kStatsValueNameResidualEchoLikelihood, - &value_in_report)); - EXPECT_EQ(rtc::ToString(sinfo.residual_echo_likelihood), - value_in_report); - EXPECT_TRUE(GetValue( - report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax, - &value_in_report)); - EXPECT_EQ(rtc::ToString(sinfo.residual_echo_likelihood_recent_max), - value_in_report); + if (sinfo.apm_statistics.delay_median_ms) { + EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian, + &value_in_report)); + EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_median_ms), + value_in_report); + } else { + EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian, + &value_in_report)); + } + if (sinfo.apm_statistics.delay_standard_deviation_ms) { + EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev, + &value_in_report)); + EXPECT_EQ( + rtc::ToString(*sinfo.apm_statistics.delay_standard_deviation_ms), + value_in_report); + } else { + EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev, + &value_in_report)); + } + if (sinfo.apm_statistics.echo_return_loss) { + EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss, + &value_in_report)); + EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss), + value_in_report); + } else { + EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss, + &value_in_report)); + } + if (sinfo.apm_statistics.echo_return_loss_enhancement) { + EXPECT_TRUE(GetValue(report, + StatsReport::kStatsValueNameEchoReturnLossEnhancement, + &value_in_report)); + EXPECT_EQ( + rtc::ToString(*sinfo.apm_statistics.echo_return_loss_enhancement), + value_in_report); + } else { + EXPECT_FALSE(GetValue(report, + StatsReport::kStatsValueNameEchoReturnLossEnhancement, + &value_in_report)); + } + if (sinfo.apm_statistics.residual_echo_likelihood) { + EXPECT_TRUE(GetValue(report, + StatsReport::kStatsValueNameResidualEchoLikelihood, + &value_in_report)); + EXPECT_EQ( + rtc::ToString(*sinfo.apm_statistics.residual_echo_likelihood), + value_in_report); + } else { + EXPECT_FALSE(GetValue(report, + StatsReport::kStatsValueNameResidualEchoLikelihood, + &value_in_report)); + } + if (sinfo.apm_statistics.residual_echo_likelihood_recent_max) { + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax, + &value_in_report)); + EXPECT_EQ(rtc::ToString( + *sinfo.apm_statistics.residual_echo_likelihood_recent_max), + value_in_report); + } else { + EXPECT_FALSE(GetValue( + report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax, + &value_in_report)); + } EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel, &value_in_report)); EXPECT_EQ(rtc::ToString(sinfo.audio_level), value_in_report); @@ -510,33 +542,27 @@ void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) { voice_sender_info->echo_return_loss_enhancement = 109; voice_sender_info->echo_delay_median_ms = 110; voice_sender_info->echo_delay_std_ms = 111; - voice_sender_info->aec_quality_min = 112.0f; voice_sender_info->typing_noise_detected = false; - voice_sender_info->ana_statistics.bitrate_action_counter = 113; - voice_sender_info->ana_statistics.channel_action_counter = 114; - voice_sender_info->ana_statistics.dtx_action_counter = 115; - voice_sender_info->ana_statistics.fec_action_counter = 116; - voice_sender_info->ana_statistics.frame_length_increase_counter = 117; - voice_sender_info->ana_statistics.frame_length_decrease_counter = 118; - voice_sender_info->ana_statistics.uplink_packet_loss_fraction = 119.0; + voice_sender_info->ana_statistics.bitrate_action_counter = 112; + voice_sender_info->ana_statistics.channel_action_counter = 113; + voice_sender_info->ana_statistics.dtx_action_counter = 114; + voice_sender_info->ana_statistics.fec_action_counter = 115; + voice_sender_info->ana_statistics.frame_length_increase_counter = 116; + voice_sender_info->ana_statistics.frame_length_decrease_counter = 117; + voice_sender_info->ana_statistics.uplink_packet_loss_fraction = 118.0; } void UpdateVoiceSenderInfoFromAudioTrack( AudioTrackInterface* audio_track, - cricket::VoiceSenderInfo* voice_sender_info) { + cricket::VoiceSenderInfo* voice_sender_info, + bool has_remote_tracks) { audio_track->GetSignalLevel(&voice_sender_info->audio_level); - webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats; - audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats); + webrtc::AudioProcessorInterface::AudioProcessorStatistics + audio_processor_stats = + audio_track->GetAudioProcessor()->GetStats(has_remote_tracks); voice_sender_info->typing_noise_detected = audio_processor_stats.typing_noise_detected; - voice_sender_info->echo_return_loss = audio_processor_stats.echo_return_loss; - voice_sender_info->echo_return_loss_enhancement = - audio_processor_stats.echo_return_loss_enhancement; - voice_sender_info->echo_delay_median_ms = - audio_processor_stats.echo_delay_median_ms; - voice_sender_info->aec_quality_min = audio_processor_stats.aec_quality_min; - voice_sender_info->echo_delay_std_ms = - audio_processor_stats.echo_delay_std_ms; + voice_sender_info->apm_statistics = audio_processor_stats.apm_statistics; } void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) { @@ -730,7 +756,8 @@ class StatsCollectorTest : public testing::Test { // Verifies the values in the track report. if (voice_sender_info) { - UpdateVoiceSenderInfoFromAudioTrack(audio_track, voice_sender_info); + UpdateVoiceSenderInfoFromAudioTrack(audio_track, voice_sender_info, + stats_read->receivers.size() > 0); VerifyVoiceSenderInfoReport(report, *voice_sender_info); } if (voice_receiver_info) { @@ -1746,7 +1773,8 @@ TEST_F(StatsCollectorTest, FilterOutNegativeInitialValues) { // Some of the contents in |voice_sender_info| needs to be updated from the // |audio_track_|. - UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info); + UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info, + true); cricket::VoiceReceiverInfo voice_receiver_info; voice_receiver_info.add_ssrc(kSsrcOfTrack); @@ -1974,7 +2002,8 @@ TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) { // Some of the contents in |voice_sender_info| needs to be updated from the // |audio_track_|. - UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info); + UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info, + true); cricket::VoiceReceiverInfo voice_receiver_info; InitVoiceReceiverInfo(&voice_receiver_info);