diff --git a/talk/media/webrtc/fakewebrtcvoiceengine.h b/talk/media/webrtc/fakewebrtcvoiceengine.h index 810896536..56dc19a32 100644 --- a/talk/media/webrtc/fakewebrtcvoiceengine.h +++ b/talk/media/webrtc/fakewebrtcvoiceengine.h @@ -1167,7 +1167,8 @@ class FakeWebRtcVoiceEngine return 0; } WEBRTC_STUB(GetEchoMetrics, (int& ERL, int& ERLE, int& RERL, int& A_NLP)); - WEBRTC_STUB(GetEcDelayMetrics, (int& delay_median, int& delay_std)); + WEBRTC_STUB(GetEcDelayMetrics, (int& delay_median, int& delay_std, + float& fraction_poor_delays)); WEBRTC_STUB(StartDebugRecording, (const char* fileNameUTF8)); WEBRTC_STUB(StartDebugRecording, (FILE* handle)); diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc index 66408f018..533e5b81e 100644 --- a/talk/media/webrtc/webrtcvoiceengine.cc +++ b/talk/media/webrtc/webrtcvoiceengine.cc @@ -3323,7 +3323,9 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { } int median, std; - if (engine()->voe()->processing()->GetEcDelayMetrics(median, std) != -1) { + float dummy; + if (engine()->voe()->processing()->GetEcDelayMetrics( + median, std, dummy) != -1) { echo_delay_median_ms = median; echo_delay_std_ms = std; } diff --git a/webrtc/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c index 2cd7d852b..60dff9471 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.c +++ b/webrtc/modules/audio_processing/aec/aec_core.c @@ -1575,7 +1575,7 @@ int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { aec->num_delay_values = 0; aec->delay_median = -1; aec->delay_std = -1; - aec->fraction_poor_delays = -1; + aec->fraction_poor_delays = -1.0f; aec->signal_delay_correction = 0; aec->previous_delay = -2; // (-2): Uninitialized. diff --git a/webrtc/voice_engine/include/voe_audio_processing.h b/webrtc/voice_engine/include/voe_audio_processing.h index 8b40360ae..162848c28 100644 --- a/webrtc/voice_engine/include/voe_audio_processing.h +++ b/webrtc/voice_engine/include/voe_audio_processing.h @@ -185,9 +185,11 @@ public: virtual int GetEchoMetrics(int& ERL, int& ERLE, int& RERL, int& A_NLP) = 0; // Gets the EC internal |delay_median| and |delay_std| in ms between - // near-end and far-end. The values are calculated over the time period - // since the last GetEcDelayMetrics() call. - virtual int GetEcDelayMetrics(int& delay_median, int& delay_std) = 0; + // near-end and far-end. The metric |fraction_poor_delays| is the amount of + // delay values that potentially can break the EC. The values are aggregated + // over one second and the last updated metrics are returned. + virtual int GetEcDelayMetrics(int& delay_median, int& delay_std, + float& fraction_poor_delays) = 0; // Enables recording of Audio Processing (AP) debugging information. // The file can later be used for off-line analysis of the AP performance. diff --git a/webrtc/voice_engine/test/auto_test/extended/ec_metrics_test.cc b/webrtc/voice_engine/test/auto_test/extended/ec_metrics_test.cc index feb36ddc0..a202aea28 100644 --- a/webrtc/voice_engine/test/auto_test/extended/ec_metrics_test.cc +++ b/webrtc/voice_engine/test/auto_test/extended/ec_metrics_test.cc @@ -41,14 +41,17 @@ TEST_F(EcMetricsTest, ManualTestEcMetrics) { int erl, erle, rerl, a_nlp; int delay_median = 0; int delay_std = 0; + float fraction_poor_delays = 0; for (int i = 0; i < 5; i++) { Sleep(1000); EXPECT_EQ(0, voe_apm_->GetEchoMetrics(erl, erle, rerl, a_nlp)); - EXPECT_EQ(0, voe_apm_->GetEcDelayMetrics(delay_median, delay_std)); + EXPECT_EQ(0, voe_apm_->GetEcDelayMetrics(delay_median, delay_std, + fraction_poor_delays)); TEST_LOG(" Echo : ERL=%5d, ERLE=%5d, RERL=%5d, A_NLP=%5d [dB], " - " delay median=%3d, delay std=%3d [ms]\n", erl, erle, rerl, a_nlp, - delay_median, delay_std); + " delay median=%3d, delay std=%3d [ms], " + "fraction_poor_delays=%3.1f [%%]\n", erl, erle, rerl, a_nlp, + delay_median, delay_std, fraction_poor_delays * 100); } EXPECT_EQ(0, voe_apm_->SetEcMetricsStatus(false)); @@ -63,8 +66,9 @@ TEST_F(EcMetricsTest, GetEcMetricsFailsIfEcNotEnabled) { TEST_F(EcMetricsTest, GetEcDelayMetricsFailsIfEcNotEnabled) { int dummy = 0; + float dummy_f = 0; EXPECT_EQ(0, voe_apm_->SetEcMetricsStatus(true)); - EXPECT_EQ(-1, voe_apm_->GetEcDelayMetrics(dummy, dummy)); + EXPECT_EQ(-1, voe_apm_->GetEcDelayMetrics(dummy, dummy, dummy_f)); EXPECT_EQ(VE_APM_ERROR, voe_base_->LastError()); } @@ -76,8 +80,11 @@ TEST_F(EcMetricsTest, ManualVerifyEcDelayMetrics) { for (int i = 0; i < 5; i++) { int delay, delay_std; - EXPECT_EQ(0, voe_apm_->GetEcDelayMetrics(delay, delay_std)); - TEST_LOG("Delay = %d, Delay Std = %d\n", delay, delay_std); + float fraction_poor_delays; + EXPECT_EQ(0, voe_apm_->GetEcDelayMetrics(delay, delay_std, + fraction_poor_delays)); + TEST_LOG("Delay = %d, Delay Std = %d, Fraction poor delays = %3.1f\n", + delay, delay_std, fraction_poor_delays * 100); Sleep(1000); } } diff --git a/webrtc/voice_engine/voe_audio_processing_impl.cc b/webrtc/voice_engine/voe_audio_processing_impl.cc index 63a4ed768..a310628ee 100644 --- a/webrtc/voice_engine/voe_audio_processing_impl.cc +++ b/webrtc/voice_engine/voe_audio_processing_impl.cc @@ -921,9 +921,10 @@ int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL, } int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median, - int& delay_std) { + int& delay_std, + float& fraction_poor_delays) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), - "GetEcDelayMetrics(median=?, std=?)"); + "GetEcDelayMetrics(median=?, std=?, fraction_poor_delays=?)"); #ifdef WEBRTC_VOICE_ENGINE_ECHO if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); @@ -937,9 +938,10 @@ int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median, int median = 0; int std = 0; + float poor_fraction = 0; // Get delay-logging values from Audio Processing Module. if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics( - &median, &std)) { + &median, &std, &poor_fraction)) { WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1), "GetEcDelayMetrics(), AudioProcessingModule delay-logging " "error"); @@ -949,10 +951,12 @@ int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median, // EC delay-logging metrics delay_median = median; delay_std = std; + fraction_poor_delays = poor_fraction; WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), - "GetEcDelayMetrics() => delay_median=%d, delay_std=%d", - delay_median, delay_std); + "GetEcDelayMetrics() => delay_median=%d, delay_std=%d, " + "fraction_poor_delays=%f", delay_median, delay_std, + fraction_poor_delays); return 0; #else _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError, diff --git a/webrtc/voice_engine/voe_audio_processing_impl.h b/webrtc/voice_engine/voe_audio_processing_impl.h index 524439d5c..26f7eec74 100644 --- a/webrtc/voice_engine/voe_audio_processing_impl.h +++ b/webrtc/voice_engine/voe_audio_processing_impl.h @@ -76,7 +76,8 @@ class VoEAudioProcessingImpl : public VoEAudioProcessing { virtual int GetEchoMetrics(int& ERL, int& ERLE, int& RERL, int& A_NLP); - virtual int GetEcDelayMetrics(int& delay_median, int& delay_std); + virtual int GetEcDelayMetrics(int& delay_median, int& delay_std, + float& fraction_poor_delays); virtual int StartDebugRecording(const char* fileNameUTF8); virtual int StartDebugRecording(FILE* file_handle);