Add generic packet rates to event_log_visualizer.

This change adds incoming & outgoing packet rates to the
event_log_visualizer.

The outgoing packet rate is drawn on the graph with outgoing RTP rate,
because we want to see it together with bandwidth estimate and probe
clusters.

The incoming packet rate is drawn separately.

Bug: webrtc:9719
Change-Id: I32648d016359af110837440ed1a5f9c31c841ea7
Reviewed-on: https://webrtc-review.googlesource.com/c/122941
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Bjorn Mellem <mellem@webrtc.org>
Commit-Queue: Peter Slatala <psla@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26696}
diff --git a/logging/rtc_event_log/logged_events.h b/logging/rtc_event_log/logged_events.h
index 5bbfa53..4bcd937 100644
--- a/logging/rtc_event_log/logged_events.h
+++ b/logging/rtc_event_log/logged_events.h
@@ -571,6 +571,9 @@
   int64_t log_time_us() const { return timestamp_us; }
   int64_t log_time_ms() const { return timestamp_us / 1000; }
 
+  size_t packet_length() const {
+    return payload_length + padding_length + overhead_length;
+  }
   int64_t timestamp_us;
   int64_t packet_number;
   size_t overhead_length;
diff --git a/logging/rtc_event_log/rtc_event_log_parser.h b/logging/rtc_event_log/rtc_event_log_parser.h
index ad5d98f..de37d31 100644
--- a/logging/rtc_event_log/rtc_event_log_parser.h
+++ b/logging/rtc_event_log/rtc_event_log_parser.h
@@ -497,14 +497,15 @@
     }
   }
 
-  const std::vector<LoggedGenericPacketReceived>& generic_packets_received() {
+  const std::vector<LoggedGenericPacketReceived>& generic_packets_received()
+      const {
     return generic_packets_received_;
   }
-  const std::vector<LoggedGenericPacketSent>& generic_packets_sent() {
+  const std::vector<LoggedGenericPacketSent>& generic_packets_sent() const {
     return generic_packets_sent_;
   }
 
-  const std::vector<LoggedGenericAckReceived>& generic_acks_received() {
+  const std::vector<LoggedGenericAckReceived>& generic_acks_received() const {
     return generic_acks_received_;
   }
 
diff --git a/rtc_tools/event_log_visualizer/analyzer.cc b/rtc_tools/event_log_visualizer/analyzer.cc
index a77f378..48cfbff 100644
--- a/rtc_tools/event_log_visualizer/analyzer.cc
+++ b/rtc_tools/event_log_visualizer/analyzer.cc
@@ -812,27 +812,29 @@
   auto window_end = packets_in_order.begin();
   size_t bytes_in_window = 0;
 
-  // Calculate a moving average of the bitrate and store in a TimeSeries.
-  TimeSeries bitrate_series("Bitrate", LineStyle::kLine);
-  for (int64_t time = config_.begin_time_;
-       time < config_.end_time_ + config_.step_; time += config_.step_) {
-    while (window_end != packets_in_order.end() && window_end->first < time) {
-      bytes_in_window += window_end->second;
-      ++window_end;
+  if (!packets_in_order.empty()) {
+    // Calculate a moving average of the bitrate and store in a TimeSeries.
+    TimeSeries bitrate_series("Bitrate", LineStyle::kLine);
+    for (int64_t time = config_.begin_time_;
+         time < config_.end_time_ + config_.step_; time += config_.step_) {
+      while (window_end != packets_in_order.end() && window_end->first < time) {
+        bytes_in_window += window_end->second;
+        ++window_end;
+      }
+      while (window_begin != packets_in_order.end() &&
+             window_begin->first < time - config_.window_duration_) {
+        RTC_DCHECK_LE(window_begin->second, bytes_in_window);
+        bytes_in_window -= window_begin->second;
+        ++window_begin;
+      }
+      float window_duration_in_seconds =
+          static_cast<float>(config_.window_duration_) / kNumMicrosecsPerSec;
+      float x = config_.GetCallTimeSec(time);
+      float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
+      bitrate_series.points.emplace_back(x, y);
     }
-    while (window_begin != packets_in_order.end() &&
-           window_begin->first < time - config_.window_duration_) {
-      RTC_DCHECK_LE(window_begin->second, bytes_in_window);
-      bytes_in_window -= window_begin->second;
-      ++window_begin;
-    }
-    float window_duration_in_seconds =
-        static_cast<float>(config_.window_duration_) / kNumMicrosecsPerSec;
-    float x = config_.GetCallTimeSec(time);
-    float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
-    bitrate_series.points.emplace_back(x, y);
+    plot->AppendTimeSeries(std::move(bitrate_series));
   }
-  plot->AppendTimeSeries(std::move(bitrate_series));
 
   // Overlay the outgoing REMB over incoming bitrate.
   TimeSeries remb_series("Remb", LineStyle::kStep);
@@ -843,6 +845,17 @@
   }
   plot->AppendTimeSeriesIfNotEmpty(std::move(remb_series));
 
+  if (!parsed_log_.generic_packets_received().empty()) {
+    TimeSeries time_series("Incoming generic bitrate", LineStyle::kLine);
+    auto GetPacketSizeKilobits = [](const LoggedGenericPacketReceived& packet) {
+      return packet.packet_length * 8.0 / 1000.0;
+    };
+    MovingAverage<LoggedGenericPacketReceived, double>(
+        GetPacketSizeKilobits, parsed_log_.generic_packets_received(), config_,
+        &time_series);
+    plot->AppendTimeSeries(std::move(time_series));
+  }
+
   plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                  "Time (s)", kLeftMargin, kRightMargin);
   plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
@@ -865,27 +878,29 @@
   auto window_end = packets_in_order.begin();
   size_t bytes_in_window = 0;
 
-  // Calculate a moving average of the bitrate and store in a TimeSeries.
-  TimeSeries bitrate_series("Bitrate", LineStyle::kLine);
-  for (int64_t time = config_.begin_time_;
-       time < config_.end_time_ + config_.step_; time += config_.step_) {
-    while (window_end != packets_in_order.end() && window_end->first < time) {
-      bytes_in_window += window_end->second;
-      ++window_end;
+  if (!packets_in_order.empty()) {
+    // Calculate a moving average of the bitrate and store in a TimeSeries.
+    TimeSeries bitrate_series("Bitrate", LineStyle::kLine);
+    for (int64_t time = config_.begin_time_;
+         time < config_.end_time_ + config_.step_; time += config_.step_) {
+      while (window_end != packets_in_order.end() && window_end->first < time) {
+        bytes_in_window += window_end->second;
+        ++window_end;
+      }
+      while (window_begin != packets_in_order.end() &&
+             window_begin->first < time - config_.window_duration_) {
+        RTC_DCHECK_LE(window_begin->second, bytes_in_window);
+        bytes_in_window -= window_begin->second;
+        ++window_begin;
+      }
+      float window_duration_in_seconds =
+          static_cast<float>(config_.window_duration_) / kNumMicrosecsPerSec;
+      float x = config_.GetCallTimeSec(time);
+      float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
+      bitrate_series.points.emplace_back(x, y);
     }
-    while (window_begin != packets_in_order.end() &&
-           window_begin->first < time - config_.window_duration_) {
-      RTC_DCHECK_LE(window_begin->second, bytes_in_window);
-      bytes_in_window -= window_begin->second;
-      ++window_begin;
-    }
-    float window_duration_in_seconds =
-        static_cast<float>(config_.window_duration_) / kNumMicrosecsPerSec;
-    float x = config_.GetCallTimeSec(time);
-    float y = bytes_in_window * 8 / window_duration_in_seconds / 1000;
-    bitrate_series.points.emplace_back(x, y);
+    plot->AppendTimeSeries(std::move(bitrate_series));
   }
-  plot->AppendTimeSeries(std::move(bitrate_series));
 
   // Overlay the send-side bandwidth estimate over the outgoing bitrate.
   TimeSeries loss_series("Loss-based estimate", LineStyle::kStep);
@@ -1005,6 +1020,32 @@
   }
   plot->AppendTimeSeriesIfNotEmpty(std::move(remb_series));
 
+  if (!parsed_log_.generic_packets_sent().empty()) {
+    {
+      TimeSeries time_series("Outgoing generic total bitrate",
+                             LineStyle::kLine);
+      auto GetPacketSizeKilobits = [](const LoggedGenericPacketSent& packet) {
+        return packet.packet_length() * 8.0 / 1000.0;
+      };
+      MovingAverage<LoggedGenericPacketSent, double>(
+          GetPacketSizeKilobits, parsed_log_.generic_packets_sent(), config_,
+          &time_series);
+      plot->AppendTimeSeries(std::move(time_series));
+    }
+
+    {
+      TimeSeries time_series("Outgoing generic payload bitrate",
+                             LineStyle::kLine);
+      auto GetPacketSizeKilobits = [](const LoggedGenericPacketSent& packet) {
+        return packet.payload_length * 8.0 / 1000.0;
+      };
+      MovingAverage<LoggedGenericPacketSent, double>(
+          GetPacketSizeKilobits, parsed_log_.generic_packets_sent(), config_,
+          &time_series);
+      plot->AppendTimeSeries(std::move(time_series));
+    }
+  }
+
   plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                  "Time (s)", kLeftMargin, kRightMargin);
   plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);