Adding NetEq lifetime stats to event log visualizer.

Bug: webrtc:9147
Change-Id: I798f8ac41192182d50df6fe98fbe56c8cb7f294c
Reviewed-on: https://webrtc-review.googlesource.com/85340
Commit-Queue: Minyue Li <minyue@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23738}
diff --git a/rtc_tools/event_log_visualizer/analyzer.cc b/rtc_tools/event_log_visualizer/analyzer.cc
index 99235e0..d20d401 100644
--- a/rtc_tools/event_log_visualizer/analyzer.cc
+++ b/rtc_tools/event_log_visualizer/analyzer.cc
@@ -1844,20 +1844,23 @@
   plot->SetTitle("NetEq timing for " + GetStreamName(kIncomingPacket, ssrc));
 }
 
-void EventLogAnalyzer::CreateNetEqStatsGraph(
+template <typename NetEqStatsType>
+void EventLogAnalyzer::CreateNetEqStatsGraphInternal(
     const NetEqStatsGetterMap& neteq_stats,
-    rtc::FunctionView<float(const NetEqNetworkStatistics&)> stats_extractor,
+    rtc::FunctionView<const std::vector<std::pair<int64_t, NetEqStatsType>>*(
+        const test::NetEqStatsGetter*)> data_extractor,
+    rtc::FunctionView<float(const NetEqStatsType&)> stats_extractor,
     const std::string& plot_name,
     Plot* plot) const {
   std::map<uint32_t, TimeSeries> time_series;
 
   for (const auto& st : neteq_stats) {
     const uint32_t ssrc = st.first;
-    const auto& stats = st.second->stats();
-
-    for (size_t i = 0; i < stats.size(); ++i) {
-      const float time = ToCallTimeSec(stats[i].first * 1000);  // ms to us.
-      const float value = stats_extractor(stats[i].second);
+    const std::vector<std::pair<int64_t, NetEqStatsType>>* data_vector =
+        data_extractor(st.second.get());
+    for (const auto& data : *data_vector) {
+      const float time = ToCallTimeSec(data.first * 1000);  // ms to us.
+      const float value = stats_extractor(data.second);
       time_series[ssrc].points.emplace_back(TimeSeriesPoint(time, value));
     }
   }
@@ -1874,6 +1877,32 @@
   plot->SetTitle(plot_name);
 }
 
+void EventLogAnalyzer::CreateNetEqNetworkStatsGraph(
+    const NetEqStatsGetterMap& neteq_stats,
+    rtc::FunctionView<float(const NetEqNetworkStatistics&)> stats_extractor,
+    const std::string& plot_name,
+    Plot* plot) const {
+  CreateNetEqStatsGraphInternal<NetEqNetworkStatistics>(
+      neteq_stats,
+      [](const test::NetEqStatsGetter* stats_getter) {
+        return stats_getter->stats();
+      },
+      stats_extractor, plot_name, plot);
+}
+
+void EventLogAnalyzer::CreateNetEqLifetimeStatsGraph(
+    const NetEqStatsGetterMap& neteq_stats,
+    rtc::FunctionView<float(const NetEqLifetimeStatistics&)> stats_extractor,
+    const std::string& plot_name,
+    Plot* plot) const {
+  CreateNetEqStatsGraphInternal<NetEqLifetimeStatistics>(
+      neteq_stats,
+      [](const test::NetEqStatsGetter* stats_getter) {
+        return stats_getter->lifetime_stats();
+      },
+      stats_extractor, plot_name, plot);
+}
+
 void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) {
   std::map<uint32_t, TimeSeries> configs_by_cp_id;
   for (const auto& config : parsed_log_.ice_candidate_pair_configs()) {
diff --git a/rtc_tools/event_log_visualizer/analyzer.h b/rtc_tools/event_log_visualizer/analyzer.h
index 6c7e056..22101b6 100644
--- a/rtc_tools/event_log_visualizer/analyzer.h
+++ b/rtc_tools/event_log_visualizer/analyzer.h
@@ -76,14 +76,20 @@
       std::map<uint32_t, std::unique_ptr<test::NetEqStatsGetter>>;
   NetEqStatsGetterMap SimulateNetEq(const std::string& replacement_file_name,
                                     int file_sample_rate_hz) const;
+
   void CreateAudioJitterBufferGraph(uint32_t ssrc,
                                     const test::NetEqStatsGetter* stats_getter,
                                     Plot* plot) const;
-  void CreateNetEqStatsGraph(
+  void CreateNetEqNetworkStatsGraph(
       const NetEqStatsGetterMap& neteq_stats_getters,
       rtc::FunctionView<float(const NetEqNetworkStatistics&)> stats_extractor,
       const std::string& plot_name,
       Plot* plot) const;
+  void CreateNetEqLifetimeStatsGraph(
+      const NetEqStatsGetterMap& neteq_stats_getters,
+      rtc::FunctionView<float(const NetEqLifetimeStatistics&)> stats_extractor,
+      const std::string& plot_name,
+      Plot* plot) const;
 
   void CreateIceCandidatePairConfigGraph(Plot* plot);
   void CreateIceConnectivityCheckGraph(Plot* plot);
@@ -122,6 +128,15 @@
     }
   }
 
+  template <typename NetEqStatsType>
+  void CreateNetEqStatsGraphInternal(
+      const NetEqStatsGetterMap& neteq_stats,
+      rtc::FunctionView<const std::vector<std::pair<int64_t, NetEqStatsType>>*(
+          const test::NetEqStatsGetter*)> data_extractor,
+      rtc::FunctionView<float(const NetEqStatsType&)> stats_extractor,
+      const std::string& plot_name,
+      Plot* plot) const;
+
   template <typename IterableType>
   void CreateAccumulatedPacketsTimeSeries(Plot* plot,
                                           const IterableType& packets,
diff --git a/rtc_tools/event_log_visualizer/main.cc b/rtc_tools/event_log_visualizer/main.cc
index 8a303b2..b1fc0d2 100644
--- a/rtc_tools/event_log_visualizer/main.cc
+++ b/rtc_tools/event_log_visualizer/main.cc
@@ -341,30 +341,36 @@
       analyzer.CreateAudioJitterBufferGraph(it->first, it->second.get(),
                                             collection->AppendNewPlot());
     }
-    analyzer.CreateNetEqStatsGraph(
+    analyzer.CreateNetEqNetworkStatsGraph(
         neteq_stats,
         [](const webrtc::NetEqNetworkStatistics& stats) {
           return stats.expand_rate / 16384.f;
         },
         "Expand rate", collection->AppendNewPlot());
-    analyzer.CreateNetEqStatsGraph(
+    analyzer.CreateNetEqNetworkStatsGraph(
         neteq_stats,
         [](const webrtc::NetEqNetworkStatistics& stats) {
           return stats.speech_expand_rate / 16384.f;
         },
         "Speech expand rate", collection->AppendNewPlot());
-    analyzer.CreateNetEqStatsGraph(
+    analyzer.CreateNetEqNetworkStatsGraph(
         neteq_stats,
         [](const webrtc::NetEqNetworkStatistics& stats) {
           return stats.accelerate_rate / 16384.f;
         },
         "Accelerate rate", collection->AppendNewPlot());
-    analyzer.CreateNetEqStatsGraph(
+    analyzer.CreateNetEqNetworkStatsGraph(
         neteq_stats,
         [](const webrtc::NetEqNetworkStatistics& stats) {
           return stats.packet_loss_rate / 16384.f;
         },
         "Packet loss rate", collection->AppendNewPlot());
+    analyzer.CreateNetEqLifetimeStatsGraph(
+        neteq_stats,
+        [](const webrtc::NetEqLifetimeStatistics& stats) {
+          return static_cast<float>(stats.concealment_events);
+        },
+        "Concealment events", collection->AppendNewPlot());
   }
 
   if (FLAG_plot_ice_candidate_pair_config) {