Add new decoding statistics for muted output

This change adds a new statistic for logging how many calls to
NetEq::GetAudio resulted in a "muted output". A muted output happens
if the packet stream has been dead for some time (and the last decoded
packet was not comfort noise).

BUG=webrtc:5606
BUG=b/31256483

Review-Url: https://codereview.webrtc.org/2341293002
Cr-Commit-Position: refs/heads/master@{#14302}
diff --git a/webrtc/modules/audio_coding/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/acm2/acm_receiver.cc
index 9a882aa..417a346 100644
--- a/webrtc/modules/audio_coding/acm2/acm_receiver.cc
+++ b/webrtc/modules/audio_coding/acm2/acm_receiver.cc
@@ -135,6 +135,7 @@
 int AcmReceiver::GetAudio(int desired_freq_hz,
                           AudioFrame* audio_frame,
                           bool* muted) {
+  RTC_DCHECK(muted);
   // Accessing members, take the lock.
   rtc::CritScope lock(&crit_sect_);
 
@@ -191,7 +192,7 @@
          sizeof(int16_t) * audio_frame->samples_per_channel_ *
              audio_frame->num_channels_);
 
-  call_stats_.DecodedByNetEq(audio_frame->speech_type_);
+  call_stats_.DecodedByNetEq(audio_frame->speech_type_, *muted);
   return 0;
 }
 
diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest_oldapi.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest_oldapi.cc
index 6220c05..2a8b834 100644
--- a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest_oldapi.cc
+++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest_oldapi.cc
@@ -253,6 +253,7 @@
   EXPECT_EQ(0, stats.decoded_cng);
   EXPECT_EQ(0, stats.decoded_plc);
   EXPECT_EQ(0, stats.decoded_plc_cng);
+  EXPECT_EQ(0, stats.decoded_muted_output);
 }
 
 // Insert some packets and pull audio. Check statistics are valid. Then,
@@ -278,6 +279,7 @@
   EXPECT_EQ(0, stats.decoded_cng);
   EXPECT_EQ(0, stats.decoded_plc);
   EXPECT_EQ(0, stats.decoded_plc_cng);
+  EXPECT_EQ(0, stats.decoded_muted_output);
 
   const int kNumPlc = 3;
   const int kNumPlcCng = 5;
@@ -293,6 +295,8 @@
   EXPECT_EQ(0, stats.decoded_cng);
   EXPECT_EQ(kNumPlc, stats.decoded_plc);
   EXPECT_EQ(kNumPlcCng, stats.decoded_plc_cng);
+  EXPECT_EQ(0, stats.decoded_muted_output);
+  // TODO(henrik.lundin) Add a test with muted state enabled.
 }
 
 TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) {
diff --git a/webrtc/modules/audio_coding/acm2/call_statistics.cc b/webrtc/modules/audio_coding/acm2/call_statistics.cc
index 4441932..7ac9fc4 100644
--- a/webrtc/modules/audio_coding/acm2/call_statistics.cc
+++ b/webrtc/modules/audio_coding/acm2/call_statistics.cc
@@ -10,14 +10,18 @@
 
 #include "webrtc/modules/audio_coding/acm2/call_statistics.h"
 
-#include <assert.h>
+#include "webrtc/base/checks.h"
 
 namespace webrtc {
 
 namespace acm2 {
 
-void CallStatistics::DecodedByNetEq(AudioFrame::SpeechType speech_type) {
+void CallStatistics::DecodedByNetEq(AudioFrame::SpeechType speech_type,
+                                    bool muted) {
   ++decoding_stat_.calls_to_neteq;
+  if (muted) {
+    ++decoding_stat_.decoded_muted_output;
+  }
   switch (speech_type) {
     case AudioFrame::kNormalSpeech: {
       ++decoding_stat_.decoded_normal;
@@ -37,7 +41,7 @@
     }
     case AudioFrame::kUndefined: {
       // If the audio is decoded by NetEq, |kUndefined| is not an option.
-      assert(false);
+      RTC_NOTREACHED();
     }
   }
 }
diff --git a/webrtc/modules/audio_coding/acm2/call_statistics.h b/webrtc/modules/audio_coding/acm2/call_statistics.h
index 888afea..3993319 100644
--- a/webrtc/modules/audio_coding/acm2/call_statistics.h
+++ b/webrtc/modules/audio_coding/acm2/call_statistics.h
@@ -37,8 +37,9 @@
   ~CallStatistics() {}
 
   // Call this method to indicate that NetEq engaged in decoding. |speech_type|
-  // is the audio-type according to NetEq.
-  void DecodedByNetEq(AudioFrame::SpeechType speech_type);
+  // is the audio-type according to NetEq, and |muted| indicates if the decoded
+  // frame was produced in muted state.
+  void DecodedByNetEq(AudioFrame::SpeechType speech_type, bool muted);
 
   // Call this method to indicate that a decoding call resulted in generating
   // silence, i.e. call to NetEq is bypassed and the output audio is zero.
diff --git a/webrtc/modules/audio_coding/acm2/call_statistics_unittest.cc b/webrtc/modules/audio_coding/acm2/call_statistics_unittest.cc
index 9ba0774..284532f 100644
--- a/webrtc/modules/audio_coding/acm2/call_statistics_unittest.cc
+++ b/webrtc/modules/audio_coding/acm2/call_statistics_unittest.cc
@@ -26,6 +26,7 @@
   EXPECT_EQ(0, stats.decoded_cng);
   EXPECT_EQ(0, stats.decoded_plc);
   EXPECT_EQ(0, stats.decoded_plc_cng);
+  EXPECT_EQ(0, stats.decoded_muted_output);
 }
 
 TEST(CallStatisticsTest, AllCalls) {
@@ -33,10 +34,10 @@
   AudioDecodingCallStats stats;
 
   call_stats.DecodedBySilenceGenerator();
-  call_stats.DecodedByNetEq(AudioFrame::kNormalSpeech);
-  call_stats.DecodedByNetEq(AudioFrame::kPLC);
-  call_stats.DecodedByNetEq(AudioFrame::kPLCCNG);
-  call_stats.DecodedByNetEq(AudioFrame::kCNG);
+  call_stats.DecodedByNetEq(AudioFrame::kNormalSpeech, false);
+  call_stats.DecodedByNetEq(AudioFrame::kPLC, false);
+  call_stats.DecodedByNetEq(AudioFrame::kPLCCNG, true);  // Let this be muted.
+  call_stats.DecodedByNetEq(AudioFrame::kCNG, false);
 
   stats = call_stats.GetDecodingStatistics();
   EXPECT_EQ(4, stats.calls_to_neteq);
@@ -45,6 +46,7 @@
   EXPECT_EQ(1, stats.decoded_cng);
   EXPECT_EQ(1, stats.decoded_plc);
   EXPECT_EQ(1, stats.decoded_plc_cng);
+  EXPECT_EQ(1, stats.decoded_muted_output);
 }
 
 }  // namespace acm2