Replacing NetEq discard rate with secondary discarded rate.

NetEq network statistics contains discard rate but has not been used and even not been implemented until recently.

According to w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsdiscarded,
this statistics needs to be replaced with an accumulative stats. Such work will be carried out separately.

Meanwhile, we need to add a rate to reflect rate of discarded redundant packets. See webrtc:8025.

In this CL, we replace the existing discard rate with secondary discarded rate, so as to
1. fulfill the requests on webrtc:8025
2. get ready to implement an accumulative statistics for discarded packets.

BUG: webrtc:7903,webrtc:8025
Change-Id: Idbf143a105db76ca15f0af54848e1448f2a810ec
Reviewed-on: https://chromium-review.googlesource.com/582863
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Minyue Li <minyue@webrtc.org>
Cr-Original-Commit-Position: refs/heads/master@{#19495}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 0c3ca753c5e9bafeb33ef304e36272aa152f45b7
diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc
index 0fbfe51..0b1d47a 100644
--- a/audio/audio_receive_stream_unittest.cc
+++ b/audio/audio_receive_stream_unittest.cc
@@ -65,7 +65,7 @@
 const CodecInst kCodecInst = {
     123, "codec_name_recv", 96000, -187, 0, -103};
 const NetworkStatistics kNetworkStats = {
-    123, 456, false, 0, 0, 789, 12, 345, 678, 901, -1, -1, -1, -1, -1, 0};
+    123, 456, false, 0, {}, 789, 12, 345, 678, 901, 0, -1, -1, -1, -1, -1, 0};
 const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
 
 struct ConfigHelper {
diff --git a/common_types.h b/common_types.h
index ecfa15d..4034d54 100644
--- a/common_types.h
+++ b/common_types.h
@@ -370,7 +370,9 @@
   // Loss rate (network + late); fraction between 0 and 1, scaled to Q14.
   uint16_t currentPacketLossRate;
   // Late loss rate; fraction between 0 and 1, scaled to Q14.
-  uint16_t currentDiscardRate;
+  union {
+    RTC_DEPRECATED uint16_t currentDiscardRate;
+  };
   // fraction (of original stream) of synthesized audio inserted through
   // expansion (in Q14)
   uint16_t currentExpandRate;
@@ -384,6 +386,8 @@
   uint16_t currentAccelerateRate;
   // fraction of data coming from secondary decoding (in Q14)
   uint16_t currentSecondaryDecodedRate;
+  // fraction of secondary data that is discarded (in Q14).
+  uint16_t currentSecondaryDiscardedRate;
   // clock-drift in parts-per-million (negative or positive)
   int32_t clockDriftPPM;
   // average packet waiting time in the jitter buffer (ms)
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index 2e0d8bc..b512f84 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -320,12 +320,12 @@
   acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms;
   acm_stat->jitterPeaksFound = neteq_stat.jitter_peaks_found ? true : false;
   acm_stat->currentPacketLossRate = neteq_stat.packet_loss_rate;
-  acm_stat->currentDiscardRate = neteq_stat.packet_discard_rate;
   acm_stat->currentExpandRate = neteq_stat.expand_rate;
   acm_stat->currentSpeechExpandRate = neteq_stat.speech_expand_rate;
   acm_stat->currentPreemptiveRate = neteq_stat.preemptive_rate;
   acm_stat->currentAccelerateRate = neteq_stat.accelerate_rate;
   acm_stat->currentSecondaryDecodedRate = neteq_stat.secondary_decoded_rate;
+  acm_stat->currentSecondaryDiscardedRate = neteq_stat.secondary_discarded_rate;
   acm_stat->clockDriftPPM = neteq_stat.clockdrift_ppm;
   acm_stat->addedSamples = neteq_stat.added_zero_samples;
   acm_stat->meanWaitingTimeMs = neteq_stat.mean_waiting_time_ms;
diff --git a/modules/audio_coding/neteq/include/neteq.h b/modules/audio_coding/neteq/include/neteq.h
index 61bdd1f..d05b76e 100644
--- a/modules/audio_coding/neteq/include/neteq.h
+++ b/modules/audio_coding/neteq/include/neteq.h
@@ -35,7 +35,6 @@
   uint16_t jitter_peaks_found;  // 1 if adding extra delay due to peaky
                                 // jitter; 0 otherwise.
   uint16_t packet_loss_rate;  // Loss rate (network + late) in Q14.
-  uint16_t packet_discard_rate;  // Late loss rate in Q14.
   uint16_t expand_rate;  // Fraction (of original stream) of synthesized
                          // audio inserted through expansion (in Q14).
   uint16_t speech_expand_rate;  // Fraction (of original stream) of synthesized
@@ -44,8 +43,10 @@
                              // expansion (in Q14).
   uint16_t accelerate_rate;  // Fraction of data removed through acceleration
                              // (in Q14).
-  uint16_t secondary_decoded_rate;  // Fraction of data coming from secondary
+  uint16_t secondary_decoded_rate;  // Fraction of data coming from FEC/RED
                                     // decoding (in Q14).
+  uint16_t secondary_discarded_rate;  // Fraction of discarded FEC/RED data (in
+                                      // Q14).
   int32_t clockdrift_ppm;  // Average clock-drift in parts-per-million
                            // (positive or negative).
   size_t added_zero_samples;  // Number of zero samples added in "off" mode.
diff --git a/modules/audio_coding/neteq/mock/mock_statistics_calculator.h b/modules/audio_coding/neteq/mock/mock_statistics_calculator.h
index da4e3ed..c854b24 100644
--- a/modules/audio_coding/neteq/mock/mock_statistics_calculator.h
+++ b/modules/audio_coding/neteq/mock/mock_statistics_calculator.h
@@ -19,8 +19,8 @@
 
 class MockStatisticsCalculator : public StatisticsCalculator {
  public:
-  // For current unittest, we mock only one method.
   MOCK_METHOD1(PacketsDiscarded, void(size_t num_packets));
+  MOCK_METHOD1(SecondaryPacketsDiscarded, void(size_t num_packets));
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/neteq_network_stats_unittest.cc b/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
index 4feb448..bfa9362 100644
--- a/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
@@ -136,12 +136,12 @@
   logic preferred_buffer_size_ms;
   logic jitter_peaks_found;
   logic packet_loss_rate;
-  logic packet_discard_rate;
   logic expand_rate;
   logic speech_expand_rate;
   logic preemptive_rate;
   logic accelerate_rate;
   logic secondary_decoded_rate;
+  logic secondary_discarded_rate;
   logic clockdrift_ppm;
   logic added_zero_samples;
   NetEqNetworkStatistics stats_ref;
@@ -201,12 +201,12 @@
     CHECK_NETEQ_NETWORK_STATS(preferred_buffer_size_ms);
     CHECK_NETEQ_NETWORK_STATS(jitter_peaks_found);
     CHECK_NETEQ_NETWORK_STATS(packet_loss_rate);
-    CHECK_NETEQ_NETWORK_STATS(packet_discard_rate);
     CHECK_NETEQ_NETWORK_STATS(expand_rate);
     CHECK_NETEQ_NETWORK_STATS(speech_expand_rate);
     CHECK_NETEQ_NETWORK_STATS(preemptive_rate);
     CHECK_NETEQ_NETWORK_STATS(accelerate_rate);
     CHECK_NETEQ_NETWORK_STATS(secondary_decoded_rate);
+    CHECK_NETEQ_NETWORK_STATS(secondary_discarded_rate);
     CHECK_NETEQ_NETWORK_STATS(clockdrift_ppm);
     CHECK_NETEQ_NETWORK_STATS(added_zero_samples);
 
@@ -249,12 +249,12 @@
       kIgnore,  // preferred_buffer_size_ms
       kIgnore,  // jitter_peaks_found
       kEqual,  // packet_loss_rate
-      kEqual,  // packet_discard_rate
       kEqual,  // expand_rate
       kEqual,  // voice_expand_rate
       kIgnore,  // preemptive_rate
       kEqual,  // accelerate_rate
       kEqual,  // decoded_fec_rate
+      kEqual,  // discarded_fec_rate
       kIgnore,  // clockdrift_ppm
       kEqual,  // added_zero_samples
       {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -273,7 +273,7 @@
     expects.stats_ref.packet_loss_rate = 0;
     expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 0;
     expects.stats_ref.secondary_decoded_rate = 2006;
-    expects.stats_ref.packet_discard_rate = 13374;
+    expects.stats_ref.secondary_discarded_rate = 14336;
     RunTest(50, expects);
   }
 
@@ -283,12 +283,12 @@
       kIgnore,  // preferred_buffer_size_ms
       kIgnore,  // jitter_peaks_found
       kEqual,  // packet_loss_rate
-      kEqual,  // packet_discard_rate
       kEqual,  // expand_rate
       kEqual,  // speech_expand_rate
       kIgnore,  // preemptive_rate
       kEqual,  // accelerate_rate
       kEqual,  // decoded_fec_rate
+      kEqual,  // discard_fec_rate
       kIgnore,  // clockdrift_ppm
       kEqual,  // added_zero_samples
       {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
diff --git a/modules/audio_coding/neteq/neteq_unittest.cc b/modules/audio_coding/neteq/neteq_unittest.cc
index 31fb74e..ec7e2bb 100644
--- a/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_unittest.cc
@@ -75,12 +75,12 @@
   stats->set_preferred_buffer_size_ms(stats_raw.preferred_buffer_size_ms);
   stats->set_jitter_peaks_found(stats_raw.jitter_peaks_found);
   stats->set_packet_loss_rate(stats_raw.packet_loss_rate);
-  stats->set_packet_discard_rate(stats_raw.packet_discard_rate);
   stats->set_expand_rate(stats_raw.expand_rate);
   stats->set_speech_expand_rate(stats_raw.speech_expand_rate);
   stats->set_preemptive_rate(stats_raw.preemptive_rate);
   stats->set_accelerate_rate(stats_raw.accelerate_rate);
   stats->set_secondary_decoded_rate(stats_raw.secondary_decoded_rate);
+  stats->set_secondary_discarded_rate(stats_raw.secondary_discarded_rate);
   stats->set_clockdrift_ppm(stats_raw.clockdrift_ppm);
   stats->set_added_zero_samples(stats_raw.added_zero_samples);
   stats->set_mean_waiting_time_ms(stats_raw.mean_waiting_time_ms);
@@ -445,10 +445,10 @@
       "759fef89a5de52bd17e733dc255c671ce86be909");
 
   const std::string network_stats_checksum =
-      PlatformChecksum("f7c2158761a531dd2804d13da0480033faa7be12",
-                       "8b5e3c8247dce48cb33923eaa1a502ca91429d5e",
-                       "f7c2158761a531dd2804d13da0480033faa7be12",
-                       "f7c2158761a531dd2804d13da0480033faa7be12");
+      PlatformChecksum("5b4262ca328e5f066af5d34f3380521583dd20de",
+                       "80235b6d727281203acb63b98f9a9e85d95f7ec0",
+                       "5b4262ca328e5f066af5d34f3380521583dd20de",
+                       "5b4262ca328e5f066af5d34f3380521583dd20de");
 
   const std::string rtcp_stats_checksum = PlatformChecksum(
       "b8880bf9fed2487efbddcb8d94b9937a29ae521d",
@@ -481,10 +481,10 @@
       "721e1e0c6effe4b2401536a4eef11512c9fb709c");
 
   const std::string network_stats_checksum =
-      PlatformChecksum("dda4cee006d9369c7114a03790c5761346cf5e23",
-                       "dda4cee006d9369c7114a03790c5761346cf5e23",
-                       "dda4cee006d9369c7114a03790c5761346cf5e23",
-                       "dda4cee006d9369c7114a03790c5761346cf5e23");
+      PlatformChecksum("4e749c46e2611877120ac7a20cbbe555cfbd70ea",
+                       "4e749c46e2611877120ac7a20cbbe555cfbd70ea",
+                       "4e749c46e2611877120ac7a20cbbe555cfbd70ea",
+                       "4e749c46e2611877120ac7a20cbbe555cfbd70ea");
 
   const std::string rtcp_stats_checksum = PlatformChecksum(
       "e37c797e3de6a64dda88c9ade7a013d022a2e1e0",
diff --git a/modules/audio_coding/neteq/neteq_unittest.proto b/modules/audio_coding/neteq/neteq_unittest.proto
index 07f21ff..344dcf6 100644
--- a/modules/audio_coding/neteq/neteq_unittest.proto
+++ b/modules/audio_coding/neteq/neteq_unittest.proto
@@ -3,16 +3,18 @@
 package webrtc.neteq_unittest;
 
 message NetEqNetworkStatistics {
+  // Next field number 18.
   optional uint32 current_buffer_size_ms = 1;
   optional uint32 preferred_buffer_size_ms = 2;
   optional uint32 jitter_peaks_found = 3;
   optional uint32 packet_loss_rate = 4;
-  optional uint32 packet_discard_rate = 5;
+  optional uint32 packet_discard_rate = 5 [deprecated = true];
   optional uint32 expand_rate = 6;
   optional uint32 speech_expand_rate = 7;
   optional uint32 preemptive_rate = 8;
   optional uint32 accelerate_rate = 9;
   optional uint32 secondary_decoded_rate = 10;
+  optional uint32 secondary_discarded_rate = 17;
   optional int32 clockdrift_ppm = 11;
   optional uint64 added_zero_samples = 12;
   optional int32 mean_waiting_time_ms = 13;
diff --git a/modules/audio_coding/neteq/packet_buffer.cc b/modules/audio_coding/neteq/packet_buffer.cc
index 1e71525..e0e2e9a 100644
--- a/modules/audio_coding/neteq/packet_buffer.cc
+++ b/modules/audio_coding/neteq/packet_buffer.cc
@@ -48,6 +48,16 @@
   auto* di2 = decoder_database.GetDecoderInfo(pt2);
   return di1 && di2 && di1->SampleRateHz() == di2->SampleRateHz();
 }
+
+void LogPacketDiscarded(int codec_level, StatisticsCalculator* stats) {
+  RTC_CHECK(stats);
+  if (codec_level > 0) {
+    stats->SecondaryPacketsDiscarded(1);
+  } else {
+    stats->PacketsDiscarded(1);
+  }
+}
+
 }  // namespace
 
 PacketBuffer::PacketBuffer(size_t max_number_of_packets,
@@ -99,8 +109,7 @@
   // timestamp as |rit|, which has a higher priority, do not insert the new
   // packet to list.
   if (rit != buffer_.rend() && packet.timestamp == rit->timestamp) {
-    RTC_CHECK(stats);
-    stats->PacketsDiscarded(1);
+    LogPacketDiscarded(packet.priority.codec_level, stats);
     return return_val;
   }
 
@@ -109,9 +118,8 @@
   // packet.
   PacketList::iterator it = rit.base();
   if (it != buffer_.end() && packet.timestamp == it->timestamp) {
+    LogPacketDiscarded(packet.priority.codec_level, stats);
     it = buffer_.erase(it);
-    RTC_CHECK(stats);
-    stats->PacketsDiscarded(1);
   }
   buffer_.insert(it, std::move(packet));  // Insert the packet at that position.
 
@@ -218,25 +226,24 @@
     return kBufferEmpty;
   }
   // Assert that the packet sanity checks in InsertPacket method works.
-  RTC_DCHECK(!buffer_.front().empty());
+  const Packet& packet = buffer_.front();
+  RTC_DCHECK(!packet.empty());
+  LogPacketDiscarded(packet.priority.codec_level, stats);
   buffer_.pop_front();
-  RTC_CHECK(stats);
-  stats->PacketsDiscarded(1);
   return kOK;
 }
 
 void PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit,
                                      uint32_t horizon_samples,
                                      StatisticsCalculator* stats) {
-  const size_t old_size = buffer_.size();
-  buffer_.remove_if([timestamp_limit, horizon_samples](const Packet& p) {
-    return timestamp_limit != p.timestamp &&
-           IsObsoleteTimestamp(p.timestamp, timestamp_limit, horizon_samples);
+  buffer_.remove_if([timestamp_limit, horizon_samples, stats](const Packet& p) {
+    if (timestamp_limit == p.timestamp ||
+        !IsObsoleteTimestamp(p.timestamp, timestamp_limit, horizon_samples)) {
+      return false;
+    }
+    LogPacketDiscarded(p.priority.codec_level, stats);
+    return true;
   });
-  if (old_size > buffer_.size()) {
-    RTC_CHECK(stats);
-    stats->PacketsDiscarded(old_size - buffer_.size());
-  }
 }
 
 void PacketBuffer::DiscardAllOldPackets(uint32_t timestamp_limit,
@@ -246,20 +253,13 @@
 
 void PacketBuffer::DiscardPacketsWithPayloadType(uint8_t payload_type,
                                                  StatisticsCalculator* stats) {
-  int packets_discarded = 0;
-  for (auto it = buffer_.begin(); it != buffer_.end(); /* */) {
-    const Packet& packet = *it;
-    if (packet.payload_type == payload_type) {
-      it = buffer_.erase(it);
-      ++packets_discarded;
-    } else {
-      ++it;
+  buffer_.remove_if([payload_type, stats](const Packet& p) {
+    if (p.payload_type != payload_type) {
+      return false;
     }
-  }
-  if (packets_discarded > 0) {
-    RTC_CHECK(stats);
-    stats->PacketsDiscarded(packets_discarded);
-  }
+    LogPacketDiscarded(p.priority.codec_level, stats);
+    return true;
+  });
 }
 
 size_t PacketBuffer::NumPacketsInBuffer() const {
diff --git a/modules/audio_coding/neteq/packet_buffer_unittest.cc b/modules/audio_coding/neteq/packet_buffer_unittest.cc
index 2622c0c..7dcf6c4 100644
--- a/modules/audio_coding/neteq/packet_buffer_unittest.cc
+++ b/modules/audio_coding/neteq/packet_buffer_unittest.cc
@@ -292,9 +292,13 @@
               packet_facts[i].payload_type,
               kFrameSize);
     Packet packet = gen.NextPacket(kPayloadLength);
-    packet.priority.red_level = packet_facts[i].primary ? 0 : 1;
+    packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
     if (packet_facts[i].extract_order < 0) {
-      EXPECT_CALL(mock_stats, PacketsDiscarded(1));
+      if (packet.priority.codec_level > 0) {
+        EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
+      } else {
+        EXPECT_CALL(mock_stats, PacketsDiscarded(1));
+      }
     }
     EXPECT_CALL(check, Call(i));
     EXPECT_EQ(PacketBuffer::kOK,
@@ -358,7 +362,8 @@
   // This will discard all remaining packets but one. The oldest packet is older
   // than the indicated horizon_samples, and will thus be left in the buffer.
   constexpr size_t kSkipPackets = 1;
-  EXPECT_CALL(mock_stats, PacketsDiscarded(kRemainingPackets - kSkipPackets));
+  EXPECT_CALL(mock_stats, PacketsDiscarded(1))
+      .Times(kRemainingPackets - kSkipPackets);
   EXPECT_CALL(check, Call(17));  // Arbitrary id number.
   buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
                            kRemainingPackets * ts_increment, &mock_stats);
diff --git a/modules/audio_coding/neteq/statistics_calculator.cc b/modules/audio_coding/neteq/statistics_calculator.cc
index 145d99a..3faed62 100644
--- a/modules/audio_coding/neteq/statistics_calculator.cc
+++ b/modules/audio_coding/neteq/statistics_calculator.cc
@@ -123,14 +123,14 @@
       lost_timestamps_(0),
       timestamps_since_last_report_(0),
       secondary_decoded_samples_(0),
+      discarded_secondary_packets_(0),
       delayed_packet_outage_counter_(
           "WebRTC.Audio.DelayedPacketOutageEventsPerMinute",
           60000,  // 60 seconds report interval.
           100),
       excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs",
                            60000,  // 60 seconds report interval.
-                           1000) {
-}
+                           1000) {}
 
 StatisticsCalculator::~StatisticsCalculator() = default;
 
@@ -141,6 +141,7 @@
   expanded_speech_samples_ = 0;
   expanded_noise_samples_ = 0;
   secondary_decoded_samples_ = 0;
+  discarded_secondary_packets_ = 0;
   waiting_times_.clear();
 }
 
@@ -184,6 +185,10 @@
   discarded_packets_ += num_packets;
 }
 
+void StatisticsCalculator::SecondaryPacketsDiscarded(size_t num_packets) {
+  discarded_secondary_packets_ += num_packets;
+}
+
 void StatisticsCalculator::LostSamples(size_t num_samples) {
   lost_timestamps_ += num_samples;
 }
@@ -249,10 +254,6 @@
   stats->packet_loss_rate =
       CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_);
 
-  const size_t discarded_samples = discarded_packets_ * samples_per_packet;
-  stats->packet_discard_rate =
-      CalculateQ14Ratio(discarded_samples, timestamps_since_last_report_);
-
   stats->accelerate_rate =
       CalculateQ14Ratio(accelerate_samples_, timestamps_since_last_report_);
 
@@ -271,6 +272,12 @@
       CalculateQ14Ratio(secondary_decoded_samples_,
                         timestamps_since_last_report_);
 
+  const size_t discarded_secondary_samples =
+      discarded_secondary_packets_ * samples_per_packet;
+  stats->secondary_discarded_rate = CalculateQ14Ratio(
+      discarded_secondary_samples,
+      discarded_secondary_samples + secondary_decoded_samples_);
+
   if (waiting_times_.size() == 0) {
     stats->mean_waiting_time_ms = -1;
     stats->median_waiting_time_ms = -1;
diff --git a/modules/audio_coding/neteq/statistics_calculator.h b/modules/audio_coding/neteq/statistics_calculator.h
index 0f8bdee..2877a16 100644
--- a/modules/audio_coding/neteq/statistics_calculator.h
+++ b/modules/audio_coding/neteq/statistics_calculator.h
@@ -66,6 +66,9 @@
   // Reports that |num_packets| packets were discarded.
   virtual void PacketsDiscarded(size_t num_packets);
 
+  // Reports that |num_packets| packets samples were discarded.
+  virtual void SecondaryPacketsDiscarded(size_t num_samples);
+
   // Reports that |num_samples| were lost.
   void LostSamples(size_t num_samples);
 
@@ -165,6 +168,7 @@
   uint32_t timestamps_since_last_report_;
   std::deque<int> waiting_times_;
   uint32_t secondary_decoded_samples_;
+  size_t discarded_secondary_packets_;
   PeriodicUmaCount delayed_packet_outage_counter_;
   PeriodicUmaAverage excess_buffer_delay_;
 
diff --git a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
index 3fd36bc..996d8d8 100644
--- a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
+++ b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
@@ -352,12 +352,12 @@
     double preferred_buffer_size_ms = 0.0;
     double jitter_peaks_found = 0.0;
     double packet_loss_rate = 0.0;
-    double packet_discard_rate = 0.0;
     double expand_rate = 0.0;
     double speech_expand_rate = 0.0;
     double preemptive_rate = 0.0;
     double accelerate_rate = 0.0;
     double secondary_decoded_rate = 0.0;
+    double secondary_discarded_rate = 0.0;
     double clockdrift_ppm = 0.0;
     double added_zero_samples = 0.0;
     double mean_waiting_time_ms = 0.0;
@@ -410,12 +410,12 @@
           a.preferred_buffer_size_ms += b.preferred_buffer_size_ms;
           a.jitter_peaks_found += b.jitter_peaks_found;
           a.packet_loss_rate += b.packet_loss_rate / 16384.0;
-          a.packet_discard_rate += b.packet_discard_rate / 16384.0;
           a.expand_rate += b.expand_rate / 16384.0;
           a.speech_expand_rate += b.speech_expand_rate / 16384.0;
           a.preemptive_rate += b.preemptive_rate / 16384.0;
           a.accelerate_rate += b.accelerate_rate / 16384.0;
           a.secondary_decoded_rate += b.secondary_decoded_rate / 16384.0;
+          a.secondary_discarded_rate += b.secondary_discarded_rate / 16384.0;
           a.clockdrift_ppm += b.clockdrift_ppm;
           a.added_zero_samples += b.added_zero_samples;
           a.mean_waiting_time_ms += b.mean_waiting_time_ms;
@@ -429,12 +429,12 @@
     sum_stats.preferred_buffer_size_ms /= stats_.size();
     sum_stats.jitter_peaks_found /= stats_.size();
     sum_stats.packet_loss_rate /= stats_.size();
-    sum_stats.packet_discard_rate /= stats_.size();
     sum_stats.expand_rate /= stats_.size();
     sum_stats.speech_expand_rate /= stats_.size();
     sum_stats.preemptive_rate /= stats_.size();
     sum_stats.accelerate_rate /= stats_.size();
     sum_stats.secondary_decoded_rate /= stats_.size();
+    sum_stats.secondary_discarded_rate /= stats_.size();
     sum_stats.clockdrift_ppm /= stats_.size();
     sum_stats.added_zero_samples /= stats_.size();
     sum_stats.mean_waiting_time_ms /= stats_.size();
@@ -644,13 +644,14 @@
   printf("  output duration: %" PRId64 " ms\n", test_duration_ms);
   auto stats = stats_getter.AverageStats();
   printf("  packet_loss_rate: %f %%\n", 100.0 * stats.packet_loss_rate);
-  printf("  packet_discard_rate: %f %%\n", 100.0 * stats.packet_discard_rate);
   printf("  expand_rate: %f %%\n", 100.0 * stats.expand_rate);
   printf("  speech_expand_rate: %f %%\n", 100.0 * stats.speech_expand_rate);
   printf("  preemptive_rate: %f %%\n", 100.0 * stats.preemptive_rate);
   printf("  accelerate_rate: %f %%\n", 100.0 * stats.accelerate_rate);
   printf("  secondary_decoded_rate: %f %%\n",
          100.0 * stats.secondary_decoded_rate);
+  printf("  secondary_discarded_rate: %f %%\n",
+         100.0 * stats.secondary_discarded_rate);
   printf("  clockdrift_ppm: %f ppm\n", stats.clockdrift_ppm);
   printf("  mean_waiting_time_ms: %f ms\n", stats.mean_waiting_time_ms);
   printf("  median_waiting_time_ms: %f ms\n", stats.median_waiting_time_ms);
diff --git a/modules/audio_coding/test/APITest.cc b/modules/audio_coding/test/APITest.cc
index d18cdef..7e67e3f 100644
--- a/modules/audio_coding/test/APITest.cc
+++ b/modules/audio_coding/test/APITest.cc
@@ -752,8 +752,6 @@
             networkStat.jitterPeaksFound);
     fprintf(stdout, "packet-size rate........ %d\n",
             networkStat.currentPacketLossRate);
-    fprintf(stdout, "discard rate............ %d\n",
-            networkStat.currentDiscardRate);
     fprintf(stdout, "expand rate............. %d\n",
             networkStat.currentExpandRate);
     fprintf(stdout, "speech expand rate...... %d\n",
@@ -764,6 +762,8 @@
             networkStat.currentAccelerateRate);
     fprintf(stdout, "Secondary decoded rate.. %d\n",
             networkStat.currentSecondaryDecodedRate);
+    fprintf(stdout, "Secondary discarded rate.%d\n",
+            networkStat.currentSecondaryDiscardedRate);
     fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
     fprintf(stdout, "Mean waiting time....... %d\n",
             networkStat.meanWaitingTimeMs);