voice_engine: Updates GetEcDelayMetrics() w.r.t. new metric

As of r8230 (https://webrtc-codereview.appspot.com/39739004/) a new Echo Delay Metric was added calculating the fraction of poor values that may cause the AEC to fail. There are currently two methods for GetDelayMetrics() in webrtc::AutioProcessing and one is deprecated.

This CL updates
- GetEcDelayMetrics()
- voe_auto_test
- talk/media/(fake)webrtcvoiceengine

BUG=N/A
TESTED=locally and trybots
R=pbos@webrtc.org, tina.legrand@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/41749004

Cr-Commit-Position: refs/heads/master@{#8251}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8251 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/fakewebrtcvoiceengine.h b/talk/media/webrtc/fakewebrtcvoiceengine.h
index 8108965..56dc19a 100644
--- a/talk/media/webrtc/fakewebrtcvoiceengine.h
+++ b/talk/media/webrtc/fakewebrtcvoiceengine.h
@@ -1167,7 +1167,8 @@
     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 66408f0..533e5b8 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -3323,7 +3323,9 @@
     }
 
     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 2cd7d85..60dff94 100644
--- a/webrtc/modules/audio_processing/aec/aec_core.c
+++ b/webrtc/modules/audio_processing/aec/aec_core.c
@@ -1575,7 +1575,7 @@
   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 8b40360..162848c 100644
--- a/webrtc/voice_engine/include/voe_audio_processing.h
+++ b/webrtc/voice_engine/include/voe_audio_processing.h
@@ -185,9 +185,11 @@
     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 feb36dd..a202aea 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 @@
   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, 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 @@
 
   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 63a4ed7..a310628 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::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 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 @@
   // 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 524439d..26f7eec 100644
--- a/webrtc/voice_engine/voe_audio_processing_impl.h
+++ b/webrtc/voice_engine/voe_audio_processing_impl.h
@@ -76,7 +76,8 @@
 
   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);