Reland of "Reporting of decoding_codec_plc events""

This is a reland of 0a88ea050cda58de81d624cf2764d46929447ed5.

The new stat will not be reported unless it is GT 0.

Reporting of decoding_codec_plc events

Bug: webrtc:10838
Change-Id: Ic8585b4eeae9a2643374f15bc2578d1141e59683
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148448
Reviewed-by: Magnus Flodman <mflodman@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Commit-Queue: Alex Narest <alexnarest@google.com>
Cr-Commit-Position: refs/heads/master@{#28797}
diff --git a/api/audio/audio_frame.h b/api/audio/audio_frame.h
index 7660e75..cda8c26 100644
--- a/api/audio/audio_frame.h
+++ b/api/audio/audio_frame.h
@@ -52,6 +52,7 @@
     kPLC = 1,
     kCNG = 2,
     kPLCCNG = 3,
+    kCodecPLC = 5,
     kUndefined = 4
   };
 
diff --git a/api/stats_types.cc b/api/stats_types.cc
index 4c69a82..441522e 100644
--- a/api/stats_types.cc
+++ b/api/stats_types.cc
@@ -489,6 +489,8 @@
       return "googDecodingNormal";
     case kStatsValueNameDecodingPLC:
       return "googDecodingPLC";
+    case kStatsValueNameDecodingCodecPLC:
+      return "googDecodingCodecPLC";
     case kStatsValueNameDecodingCNG:
       return "googDecodingCNG";
     case kStatsValueNameDecodingPLCCNG:
diff --git a/api/stats_types.h b/api/stats_types.h
index 0e97eaf..5b8ad4f 100644
--- a/api/stats_types.h
+++ b/api/stats_types.h
@@ -163,6 +163,7 @@
     kStatsValueNameDecodingMutedOutput,
     kStatsValueNameDecodingNormal,
     kStatsValueNameDecodingPLC,
+    kStatsValueNameDecodingCodecPLC,
     kStatsValueNameDecodingPLCCNG,
     kStatsValueNameDer,
     kStatsValueNameDtlsCipher,
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index 1a55adb..c4abea0 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -239,7 +239,8 @@
   stats.decoding_calls_to_silence_generator = ds.calls_to_silence_generator;
   stats.decoding_calls_to_neteq = ds.calls_to_neteq;
   stats.decoding_normal = ds.decoded_normal;
-  stats.decoding_plc = ds.decoded_plc;
+  stats.decoding_plc = ds.decoded_neteq_plc;
+  stats.decoding_codec_plc = ds.decoded_codec_plc;
   stats.decoding_cng = ds.decoded_cng;
   stats.decoding_plc_cng = ds.decoded_plc_cng;
   stats.decoding_muted_output = ds.decoded_muted_output;
diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc
index 762dba7..12e779d 100644
--- a/audio/audio_receive_stream_unittest.cc
+++ b/audio/audio_receive_stream_unittest.cc
@@ -43,7 +43,8 @@
   audio_decode_stats.calls_to_silence_generator = 234;
   audio_decode_stats.calls_to_neteq = 567;
   audio_decode_stats.decoded_normal = 890;
-  audio_decode_stats.decoded_plc = 123;
+  audio_decode_stats.decoded_neteq_plc = 123;
+  audio_decode_stats.decoded_codec_plc = 124;
   audio_decode_stats.decoded_cng = 456;
   audio_decode_stats.decoded_plc_cng = 789;
   audio_decode_stats.decoded_muted_output = 987;
@@ -306,7 +307,8 @@
             stats.decoding_calls_to_silence_generator);
   EXPECT_EQ(kAudioDecodeStats.calls_to_neteq, stats.decoding_calls_to_neteq);
   EXPECT_EQ(kAudioDecodeStats.decoded_normal, stats.decoding_normal);
-  EXPECT_EQ(kAudioDecodeStats.decoded_plc, stats.decoding_plc);
+  EXPECT_EQ(kAudioDecodeStats.decoded_neteq_plc, stats.decoding_plc);
+  EXPECT_EQ(kAudioDecodeStats.decoded_codec_plc, stats.decoding_codec_plc);
   EXPECT_EQ(kAudioDecodeStats.decoded_cng, stats.decoding_cng);
   EXPECT_EQ(kAudioDecodeStats.decoded_plc_cng, stats.decoding_plc_cng);
   EXPECT_EQ(kAudioDecodeStats.decoded_muted_output,
diff --git a/call/audio_receive_stream.h b/call/audio_receive_stream.h
index 1829228..b16a053 100644
--- a/call/audio_receive_stream.h
+++ b/call/audio_receive_stream.h
@@ -72,7 +72,9 @@
     int32_t decoding_calls_to_silence_generator = 0;
     int32_t decoding_calls_to_neteq = 0;
     int32_t decoding_normal = 0;
+    // TODO(alexnarest): Consider decoding_neteq_plc for consistency
     int32_t decoding_plc = 0;
+    int32_t decoding_codec_plc = 0;
     int32_t decoding_cng = 0;
     int32_t decoding_plc_cng = 0;
     int32_t decoding_muted_output = 0;
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index 856dba4..2909126 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -522,7 +522,9 @@
   int decoding_calls_to_silence_generator = 0;
   int decoding_calls_to_neteq = 0;
   int decoding_normal = 0;
+  // TODO(alexnarest): Consider decoding_neteq_plc for consistency
   int decoding_plc = 0;
+  int decoding_codec_plc = 0;
   int decoding_cng = 0;
   int decoding_plc_cng = 0;
   int decoding_muted_output = 0;
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index 7877b2c..540623e 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -2238,6 +2238,7 @@
     rinfo.decoding_calls_to_neteq = stats.decoding_calls_to_neteq;
     rinfo.decoding_normal = stats.decoding_normal;
     rinfo.decoding_plc = stats.decoding_plc;
+    rinfo.decoding_codec_plc = stats.decoding_codec_plc;
     rinfo.decoding_cng = stats.decoding_cng;
     rinfo.decoding_plc_cng = stats.decoding_plc_cng;
     rinfo.decoding_muted_output = stats.decoding_muted_output;
diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc
index 3eec446..91fcfeb 100644
--- a/media/engine/webrtc_voice_engine_unittest.cc
+++ b/media/engine/webrtc_voice_engine_unittest.cc
@@ -670,6 +670,7 @@
     stats.decoding_calls_to_neteq = 345;
     stats.decoding_normal = 67890;
     stats.decoding_plc = 1234;
+    stats.decoding_codec_plc = 1236;
     stats.decoding_cng = 5678;
     stats.decoding_plc_cng = 9012;
     stats.decoding_muted_output = 3456;
@@ -719,6 +720,7 @@
     EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
     EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
     EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
+    EXPECT_EQ(info.decoding_codec_plc, stats.decoding_codec_plc);
     EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
     EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
     EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index 64a681d..f7513f7 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -266,7 +266,7 @@
   EXPECT_EQ(0, stats.calls_to_silence_generator);
   EXPECT_EQ(0, stats.decoded_normal);
   EXPECT_EQ(0, stats.decoded_cng);
-  EXPECT_EQ(0, stats.decoded_plc);
+  EXPECT_EQ(0, stats.decoded_neteq_plc);
   EXPECT_EQ(0, stats.decoded_plc_cng);
   EXPECT_EQ(0, stats.decoded_muted_output);
 }
@@ -292,7 +292,7 @@
   EXPECT_EQ(0, stats.calls_to_silence_generator);
   EXPECT_EQ(kNumNormalCalls, stats.decoded_normal);
   EXPECT_EQ(0, stats.decoded_cng);
-  EXPECT_EQ(0, stats.decoded_plc);
+  EXPECT_EQ(0, stats.decoded_neteq_plc);
   EXPECT_EQ(0, stats.decoded_plc_cng);
   EXPECT_EQ(0, stats.decoded_muted_output);
 
@@ -308,7 +308,7 @@
   EXPECT_EQ(0, stats.calls_to_silence_generator);
   EXPECT_EQ(kNumNormalCalls, stats.decoded_normal);
   EXPECT_EQ(0, stats.decoded_cng);
-  EXPECT_EQ(kNumPlc, stats.decoded_plc);
+  EXPECT_EQ(kNumPlc, stats.decoded_neteq_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.
diff --git a/modules/audio_coding/acm2/call_statistics.cc b/modules/audio_coding/acm2/call_statistics.cc
index a506ead..e97e529 100644
--- a/modules/audio_coding/acm2/call_statistics.cc
+++ b/modules/audio_coding/acm2/call_statistics.cc
@@ -28,7 +28,11 @@
       break;
     }
     case AudioFrame::kPLC: {
-      ++decoding_stat_.decoded_plc;
+      ++decoding_stat_.decoded_neteq_plc;
+      break;
+    }
+    case AudioFrame::kCodecPLC: {
+      ++decoding_stat_.decoded_codec_plc;
       break;
     }
     case AudioFrame::kCNG: {
diff --git a/modules/audio_coding/acm2/call_statistics_unittest.cc b/modules/audio_coding/acm2/call_statistics_unittest.cc
index d7ac953..b96977b 100644
--- a/modules/audio_coding/acm2/call_statistics_unittest.cc
+++ b/modules/audio_coding/acm2/call_statistics_unittest.cc
@@ -25,7 +25,7 @@
   EXPECT_EQ(0, stats.calls_to_silence_generator);
   EXPECT_EQ(0, stats.decoded_normal);
   EXPECT_EQ(0, stats.decoded_cng);
-  EXPECT_EQ(0, stats.decoded_plc);
+  EXPECT_EQ(0, stats.decoded_neteq_plc);
   EXPECT_EQ(0, stats.decoded_plc_cng);
   EXPECT_EQ(0, stats.decoded_muted_output);
 }
@@ -37,15 +37,17 @@
   call_stats.DecodedBySilenceGenerator();
   call_stats.DecodedByNetEq(AudioFrame::kNormalSpeech, false);
   call_stats.DecodedByNetEq(AudioFrame::kPLC, false);
+  call_stats.DecodedByNetEq(AudioFrame::kCodecPLC, 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);
+  EXPECT_EQ(5, stats.calls_to_neteq);
   EXPECT_EQ(1, stats.calls_to_silence_generator);
   EXPECT_EQ(1, stats.decoded_normal);
   EXPECT_EQ(1, stats.decoded_cng);
-  EXPECT_EQ(1, stats.decoded_plc);
+  EXPECT_EQ(1, stats.decoded_neteq_plc);
+  EXPECT_EQ(1, stats.decoded_codec_plc);
   EXPECT_EQ(1, stats.decoded_plc_cng);
   EXPECT_EQ(1, stats.decoded_muted_output);
 }
diff --git a/modules/audio_coding/include/audio_coding_module_typedefs.h b/modules/audio_coding/include/audio_coding_module_typedefs.h
index d256fd1..95314a3 100644
--- a/modules/audio_coding/include/audio_coding_module_typedefs.h
+++ b/modules/audio_coding/include/audio_coding_module_typedefs.h
@@ -57,7 +57,8 @@
       : calls_to_silence_generator(0),
         calls_to_neteq(0),
         decoded_normal(0),
-        decoded_plc(0),
+        decoded_neteq_plc(0),
+        decoded_codec_plc(0),
         decoded_cng(0),
         decoded_plc_cng(0),
         decoded_muted_output(0) {}
@@ -66,7 +67,8 @@
                                    // and NetEq was disengaged from decoding.
   int calls_to_neteq;              // Number of calls to NetEq.
   int decoded_normal;  // Number of calls where audio RTP packet decoded.
-  int decoded_plc;     // Number of calls resulted in PLC.
+  int decoded_neteq_plc;  // Number of calls resulted in NetEq PLC.
+  int decoded_codec_plc;  // Number of calls resulted in codec PLC.
   int decoded_cng;  // Number of calls where comfort noise generated due to DTX.
   int decoded_plc_cng;       // Number of calls resulted where PLC faded to CNG.
   int decoded_muted_output;  // Number of calls returning a muted state output.
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index 8ef08ce..5466409 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -203,6 +203,11 @@
       audio_frame->vad_activity_ = AudioFrame::kVadPassive;
       break;
     }
+    case NetEqImpl::OutputType::kCodecPLC: {
+      audio_frame->speech_type_ = AudioFrame::kCodecPLC;
+      audio_frame->vad_activity_ = last_vad_activity;
+      break;
+    }
     default:
       RTC_NOTREACHED();
   }
@@ -2088,6 +2093,8 @@
     return OutputType::kPLC;
   } else if (vad_->running() && !vad_->active_speech()) {
     return OutputType::kVadPassive;
+  } else if (last_mode_ == kModeCodecPlc) {
+    return OutputType::kCodecPLC;
   } else {
     return OutputType::kNormalSpeech;
   }
diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h
index 9e1af10..c4887a7 100644
--- a/modules/audio_coding/neteq/neteq_impl.h
+++ b/modules/audio_coding/neteq/neteq_impl.h
@@ -64,7 +64,14 @@
 
 class NetEqImpl : public webrtc::NetEq {
  public:
-  enum class OutputType { kNormalSpeech, kPLC, kCNG, kPLCCNG, kVadPassive };
+  enum class OutputType {
+    kNormalSpeech,
+    kPLC,
+    kCNG,
+    kPLCCNG,
+    kVadPassive,
+    kCodecPLC
+  };
 
   enum ErrorCodes {
     kNoError = 0,
diff --git a/pc/stats_collector.cc b/pc/stats_collector.cc
index 25386f0..37b4b4b 100644
--- a/pc/stats_collector.cc
+++ b/pc/stats_collector.cc
@@ -176,6 +176,9 @@
     report->AddInt(StatsReport::kStatsValueNameAudioOutputLevel,
                    info.audio_level);
   }
+  if (info.decoding_codec_plc)
+    report->AddInt(StatsReport::kStatsValueNameDecodingCodecPLC,
+                   info.decoding_codec_plc);
 
   report->AddInt64(StatsReport::kStatsValueNameBytesReceived, info.bytes_rcvd);
   if (info.capture_start_ntp_time_ms >= 0) {
diff --git a/pc/stats_collector_unittest.cc b/pc/stats_collector_unittest.cc
index 82f219e..7e717f6 100644
--- a/pc/stats_collector_unittest.cc
+++ b/pc/stats_collector_unittest.cc
@@ -374,6 +374,9 @@
   EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLC,
                        &value_in_report));
   EXPECT_EQ(rtc::ToString(info.decoding_plc), value_in_report);
+  EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCodecPLC,
+                       &value_in_report));
+  EXPECT_EQ(rtc::ToString(info.decoding_codec_plc), value_in_report);
   EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCNG,
                        &value_in_report));
   EXPECT_EQ(rtc::ToString(info.decoding_cng), value_in_report);
@@ -577,6 +580,7 @@
   voice_receiver_info->accelerate_rate = 124;
   voice_receiver_info->preemptive_expand_rate = 125;
   voice_receiver_info->secondary_discarded_rate = 126;
+  voice_receiver_info->decoding_codec_plc = 127;
 }
 
 class StatsCollectorForTest : public StatsCollector {