/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_tools/rtc_event_log_visualizer/analyzer.h"

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <unordered_set>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/functional/bind_front.h"
#include "absl/strings/string_view.h"
#include "api/candidate.h"
#include "api/dtls_transport_interface.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "api/function_view.h"
#include "api/media_types.h"
#include "api/rtp_headers.h"
#include "api/transport/bandwidth_usage.h"
#include "api/transport/ecn_marking.h"
#include "api/transport/goog_cc_factory.h"
#include "api/transport/network_control.h"
#include "api/transport/network_types.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
#include "logging/rtc_event_log/rtc_event_log_parser.h"
#include "logging/rtc_event_log/rtc_event_processor.h"
#include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_interface.h"
#include "modules/congestion_controller/include/receive_side_congestion_controller.h"
#include "modules/congestion_controller/rtp/transport_feedback_adapter.h"
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet/congestion_control_feedback.h"
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/numerics/sequence_number_unwrapper.h"
#include "rtc_base/rate_statistics.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_tools/rtc_event_log_visualizer/analyze_audio.h"
#include "rtc_tools/rtc_event_log_visualizer/analyzer_common.h"
#include "rtc_tools/rtc_event_log_visualizer/log_simulation.h"
#include "rtc_tools/rtc_event_log_visualizer/plot_base.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

namespace {

std::string SsrcToString(uint32_t ssrc) {
  StringBuilder ss;
  ss << "SSRC " << ssrc;
  return ss.Release();
}

// Checks whether an SSRC is contained in the list of desired SSRCs.
// Note that an empty SSRC list matches every SSRC.
bool MatchingSsrc(uint32_t ssrc, const std::vector<uint32_t>& desired_ssrc) {
  if (desired_ssrc.empty())
    return true;
  return std::find(desired_ssrc.begin(), desired_ssrc.end(), ssrc) !=
         desired_ssrc.end();
}

double AbsSendTimeToMicroseconds(int64_t abs_send_time) {
  // The timestamp is a fixed point representation with 6 bits for seconds
  // and 18 bits for fractions of a second. Thus, we divide by 2^18 to get the
  // time in seconds and then multiply by kNumMicrosecsPerSec to convert to
  // microseconds.
  static constexpr double kTimestampToMicroSec =
      static_cast<double>(kNumMicrosecsPerSec) / static_cast<double>(1ul << 18);
  return abs_send_time * kTimestampToMicroSec;
}

// Computes the difference `later` - `earlier` where `later` and `earlier`
// are counters that wrap at `modulus`. The difference is chosen to have the
// least absolute value. For example if `modulus` is 8, then the difference will
// be chosen in the range [-3, 4]. If `modulus` is 9, then the difference will
// be in [-4, 4].
int64_t WrappingDifference(uint32_t later, uint32_t earlier, int64_t modulus) {
  RTC_DCHECK_LE(1, modulus);
  RTC_DCHECK_LT(later, modulus);
  RTC_DCHECK_LT(earlier, modulus);
  int64_t difference =
      static_cast<int64_t>(later) - static_cast<int64_t>(earlier);
  int64_t max_difference = modulus / 2;
  int64_t min_difference = max_difference - modulus + 1;
  if (difference > max_difference) {
    difference -= modulus;
  }
  if (difference < min_difference) {
    difference += modulus;
  }
  if (difference > max_difference / 2 || difference < min_difference / 2) {
    RTC_LOG(LS_WARNING) << "Difference between" << later << " and " << earlier
                        << " expected to be in the range ("
                        << min_difference / 2 << "," << max_difference / 2
                        << ") but is " << difference
                        << ". Correct unwrapping is uncertain.";
  }
  return difference;
}

// This is much more reliable for outgoing streams than for incoming streams.
template <typename RtpPacketContainer>
std::optional<uint32_t> EstimateRtpClockFrequency(
    const RtpPacketContainer& packets,
    int64_t end_time_us) {
  RTC_CHECK(packets.size() >= 2);
  SeqNumUnwrapper<uint32_t> unwrapper;
  int64_t first_rtp_timestamp =
      unwrapper.Unwrap(packets[0].rtp.header.timestamp);
  int64_t first_log_timestamp = packets[0].log_time_us();
  int64_t last_rtp_timestamp = first_rtp_timestamp;
  int64_t last_log_timestamp = first_log_timestamp;
  for (size_t i = 1; i < packets.size(); i++) {
    if (packets[i].log_time_us() > end_time_us)
      break;
    last_rtp_timestamp = unwrapper.Unwrap(packets[i].rtp.header.timestamp);
    last_log_timestamp = packets[i].log_time_us();
  }
  if (last_log_timestamp - first_log_timestamp < kNumMicrosecsPerSec) {
    RTC_LOG(LS_WARNING)
        << "Failed to estimate RTP clock frequency: Stream too short. ("
        << packets.size() << " packets, "
        << last_log_timestamp - first_log_timestamp << " us)";
    return std::nullopt;
  }
  double duration =
      static_cast<double>(last_log_timestamp - first_log_timestamp) /
      kNumMicrosecsPerSec;
  double estimated_frequency =
      (last_rtp_timestamp - first_rtp_timestamp) / duration;
  for (uint32_t f : {8000, 16000, 32000, 48000, 90000}) {
    if (std::fabs(estimated_frequency - f) < 0.15 * f) {
      return f;
    }
  }
  RTC_LOG(LS_WARNING) << "Failed to estimate RTP clock frequency: Estimate "
                      << estimated_frequency
                      << " not close to any standard RTP frequency."
                      << " Last timestamp " << last_rtp_timestamp
                      << " first timestamp " << first_rtp_timestamp;
  return std::nullopt;
}

std::optional<double> NetworkDelayDiff_AbsSendTime(
    const LoggedRtpPacketIncoming& old_packet,
    const LoggedRtpPacketIncoming& new_packet) {
  if (old_packet.rtp.header.extension.hasAbsoluteSendTime &&
      new_packet.rtp.header.extension.hasAbsoluteSendTime) {
    int64_t send_time_diff = WrappingDifference(
        new_packet.rtp.header.extension.absoluteSendTime,
        old_packet.rtp.header.extension.absoluteSendTime, 1ul << 24);
    int64_t recv_time_diff =
        new_packet.log_time_us() - old_packet.log_time_us();
    double delay_change_us =
        recv_time_diff - AbsSendTimeToMicroseconds(send_time_diff);
    return delay_change_us / 1000;
  } else {
    return std::nullopt;
  }
}

std::optional<double> NetworkDelayDiff_CaptureTime(
    const LoggedRtpPacketIncoming& old_packet,
    const LoggedRtpPacketIncoming& new_packet,
    const double sample_rate) {
  int64_t send_time_diff =
      WrappingDifference(new_packet.rtp.header.timestamp,
                         old_packet.rtp.header.timestamp, 1ull << 32);
  int64_t recv_time_diff = new_packet.log_time_us() - old_packet.log_time_us();

  double delay_change =
      static_cast<double>(recv_time_diff) / 1000 -
      static_cast<double>(send_time_diff) / sample_rate * 1000;
  if (delay_change < -10000 || 10000 < delay_change) {
    RTC_LOG(LS_WARNING) << "Very large delay change. Timestamps correct?";
    RTC_LOG(LS_WARNING) << "Old capture time "
                        << old_packet.rtp.header.timestamp << ", received time "
                        << old_packet.log_time_us();
    RTC_LOG(LS_WARNING) << "New capture time "
                        << new_packet.rtp.header.timestamp << ", received time "
                        << new_packet.log_time_us();
    RTC_LOG(LS_WARNING) << "Receive time difference " << recv_time_diff << " = "
                        << static_cast<double>(recv_time_diff) /
                               kNumMicrosecsPerSec
                        << "s";
    RTC_LOG(LS_WARNING) << "Send time difference " << send_time_diff << " = "
                        << static_cast<double>(send_time_diff) / sample_rate
                        << "s";
  }
  return delay_change;
}

template <typename T>
TimeSeries CreateRtcpTypeTimeSeries(const std::vector<T>& rtcp_list,
                                    AnalyzerConfig config,
                                    std::string rtcp_name,
                                    int category_id) {
  TimeSeries time_series(rtcp_name, LineStyle::kNone, PointStyle::kHighlight);
  for (const auto& rtcp : rtcp_list) {
    float x = config.GetCallTimeSec(rtcp.timestamp);
    float y = category_id;
    time_series.points.emplace_back(x, y);
  }
  return time_series;
}

const char kUnknownEnumValue[] = "unknown";

// TODO(tommi): This should be "host".
const char kIceCandidateTypeLocal[] = "local";
// TODO(tommi): This should be "srflx".
const char kIceCandidateTypeStun[] = "stun";
const char kIceCandidateTypePrflx[] = "prflx";
const char kIceCandidateTypeRelay[] = "relay";

const char kProtocolUdp[] = "udp";
const char kProtocolTcp[] = "tcp";
const char kProtocolSsltcp[] = "ssltcp";
const char kProtocolTls[] = "tls";

const char kAddressFamilyIpv4[] = "ipv4";
const char kAddressFamilyIpv6[] = "ipv6";

const char kNetworkTypeEthernet[] = "ethernet";
const char kNetworkTypeLoopback[] = "loopback";
const char kNetworkTypeWifi[] = "wifi";
const char kNetworkTypeVpn[] = "vpn";
const char kNetworkTypeCellular[] = "cellular";

absl::string_view GetIceCandidateTypeAsString(IceCandidateType type) {
  switch (type) {
    case IceCandidateType::kHost:
      return kIceCandidateTypeLocal;
    case IceCandidateType::kSrflx:
      return kIceCandidateTypeStun;
    case IceCandidateType::kPrflx:
      return kIceCandidateTypePrflx;
    case IceCandidateType::kRelay:
      return kIceCandidateTypeRelay;
    default:
      RTC_DCHECK_NOTREACHED();
      return kUnknownEnumValue;
  }
}

std::string GetProtocolAsString(IceCandidatePairProtocol protocol) {
  switch (protocol) {
    case IceCandidatePairProtocol::kUdp:
      return kProtocolUdp;
    case IceCandidatePairProtocol::kTcp:
      return kProtocolTcp;
    case IceCandidatePairProtocol::kSsltcp:
      return kProtocolSsltcp;
    case IceCandidatePairProtocol::kTls:
      return kProtocolTls;
    default:
      return kUnknownEnumValue;
  }
}

std::string GetAddressFamilyAsString(IceCandidatePairAddressFamily family) {
  switch (family) {
    case IceCandidatePairAddressFamily::kIpv4:
      return kAddressFamilyIpv4;
    case IceCandidatePairAddressFamily::kIpv6:
      return kAddressFamilyIpv6;
    default:
      return kUnknownEnumValue;
  }
}

std::string GetNetworkTypeAsString(IceCandidateNetworkType type) {
  switch (type) {
    case IceCandidateNetworkType::kEthernet:
      return kNetworkTypeEthernet;
    case IceCandidateNetworkType::kLoopback:
      return kNetworkTypeLoopback;
    case IceCandidateNetworkType::kWifi:
      return kNetworkTypeWifi;
    case IceCandidateNetworkType::kVpn:
      return kNetworkTypeVpn;
    case IceCandidateNetworkType::kCellular:
      return kNetworkTypeCellular;
    default:
      return kUnknownEnumValue;
  }
}

std::string GetCandidatePairLogDescriptionAsString(
    const LoggedIceCandidatePairConfig& config) {
  // Example: stun:wifi->relay(tcp):cellular@udp:ipv4
  // represents a pair of a local server-reflexive candidate on a WiFi network
  // and a remote relay candidate using TCP as the relay protocol on a cell
  // network, when the candidate pair communicates over UDP using IPv4.
  StringBuilder ss;
  ss << GetIceCandidateTypeAsString(config.local_candidate_type);

  if (config.local_candidate_type == IceCandidateType::kRelay) {
    ss << "(" << GetProtocolAsString(config.local_relay_protocol) << ")";
  }

  ss << ":" << GetNetworkTypeAsString(config.local_network_type) << ":"
     << GetAddressFamilyAsString(config.local_address_family) << "->"
     << GetIceCandidateTypeAsString(config.remote_candidate_type) << ":"
     << GetAddressFamilyAsString(config.remote_address_family) << "@"
     << GetProtocolAsString(config.candidate_pair_protocol);
  return ss.Release();
}

std::string GetDirectionAsString(PacketDirection direction) {
  if (direction == kIncomingPacket) {
    return "Incoming";
  } else {
    return "Outgoing";
  }
}

std::string GetDirectionAsShortString(PacketDirection direction) {
  if (direction == kIncomingPacket) {
    return "In";
  } else {
    return "Out";
  }
}

struct FakeExtensionSmall {
  static constexpr RTPExtensionType kId = kRtpExtensionMid;
  static constexpr absl::string_view Uri() { return "fake-extension-small"; }
};
struct FakeExtensionLarge {
  static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId;
  static constexpr absl::string_view Uri() { return "fake-extension-large"; }
};

RtpPacketReceived RtpPacketForBWEFromHeader(const RTPHeader& header) {
  RtpHeaderExtensionMap rtp_header_extensions(/*extmap_allow_mixed=*/true);
  // ReceiveSideCongestionController doesn't need to know extensions ids as
  // long as it able to get extensions by type. So any ids would work here.
  rtp_header_extensions.Register<TransmissionOffset>(1);
  rtp_header_extensions.Register<AbsoluteSendTime>(2);
  rtp_header_extensions.Register<TransportSequenceNumber>(3);
  rtp_header_extensions.Register<FakeExtensionSmall>(4);
  // Use id > 14 to force two byte header per rtp header when this one is used.
  rtp_header_extensions.Register<FakeExtensionLarge>(16);

  RtpPacketReceived rtp_packet(&rtp_header_extensions);
  // Set only fields that might be relevant for the bandwidth estimatior.
  rtp_packet.SetSsrc(header.ssrc);
  rtp_packet.SetTimestamp(header.timestamp);
  size_t num_bwe_extensions = 0;
  if (header.extension.hasTransmissionTimeOffset) {
    rtp_packet.SetExtension<TransmissionOffset>(
        header.extension.transmissionTimeOffset);
    ++num_bwe_extensions;
  }
  if (header.extension.hasAbsoluteSendTime) {
    rtp_packet.SetExtension<AbsoluteSendTime>(
        header.extension.absoluteSendTime);
    ++num_bwe_extensions;
  }
  if (header.extension.hasTransportSequenceNumber) {
    rtp_packet.SetExtension<TransportSequenceNumber>(
        header.extension.transportSequenceNumber);
    ++num_bwe_extensions;
  }

  // All parts of the RTP header are 32bit aligned.
  RTC_CHECK_EQ(header.headerLength % 4, 0);

  // Original packet could have more extensions, there could be csrcs that are
  // not propagated by the rtc event log, i.e. logged header size might be
  // larger that rtp_packet.header_size(). Increase it by setting an extra fake
  // extension.
  RTC_CHECK_GE(header.headerLength, rtp_packet.headers_size());
  size_t bytes_to_add = header.headerLength - rtp_packet.headers_size();
  if (bytes_to_add > 0) {
    if (bytes_to_add <= 16) {
      // one-byte header rtp header extension allows to add up to 16 bytes.
      rtp_packet.AllocateExtension(FakeExtensionSmall::kId, bytes_to_add - 1);
    } else {
      // two-byte header rtp header extension would also add one byte per
      // already set extension.
      rtp_packet.AllocateExtension(FakeExtensionLarge::kId,
                                   bytes_to_add - 2 - num_bwe_extensions);
    }
  }
  RTC_CHECK_EQ(rtp_packet.headers_size(), header.headerLength);

  return rtp_packet;
}

struct PacketLossSummary {
  size_t num_packets = 0;
  size_t num_lost_packets = 0;
  Timestamp base_time = Timestamp::MinusInfinity();
};

float GetHighestSeqNumber(const rtcp::ReportBlock& block) {
  return block.extended_high_seq_num();
}

float GetFractionLost(const rtcp::ReportBlock& block) {
  return static_cast<double>(block.fraction_lost()) / 256 * 100;
}

float GetCumulativeLost(const rtcp::ReportBlock& block) {
  return block.cumulative_lost();
}

float DelaySinceLastSr(const rtcp::ReportBlock& block) {
  return static_cast<double>(block.delay_since_last_sr()) / 65536;
}

std::map<uint32_t, std::string> BuildCandidateIdLogDescriptionMap(
    const std::vector<LoggedIceCandidatePairConfig>&
        ice_candidate_pair_configs) {
  std::map<uint32_t, std::string> candidate_pair_desc_by_id;
  for (const auto& config : ice_candidate_pair_configs) {
    // TODO(qingsi): Add the handling of the "Updated" config event after the
    // visualization of property change for candidate pairs is introduced.
    if (candidate_pair_desc_by_id.find(config.candidate_pair_id) ==
        candidate_pair_desc_by_id.end()) {
      const std::string candidate_pair_desc =
          GetCandidatePairLogDescriptionAsString(config);
      candidate_pair_desc_by_id[config.candidate_pair_id] = candidate_pair_desc;
    }
  }
  return candidate_pair_desc_by_id;
}

}  // namespace

EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log,
                                   bool normalize_time)
    : env_(CreateEnvironment()), parsed_log_(log) {
  config_.window_duration_ = TimeDelta::Millis(250);
  config_.step_ = TimeDelta::Millis(10);
  if (!log.start_log_events().empty()) {
    config_.rtc_to_utc_offset_ = log.start_log_events()[0].utc_time() -
                                 log.start_log_events()[0].log_time();
  }
  config_.normalize_time_ = normalize_time;
  config_.begin_time_ = parsed_log_.first_timestamp();
  config_.end_time_ = parsed_log_.last_timestamp();
  if (config_.end_time_ < config_.begin_time_) {
    RTC_LOG(LS_WARNING) << "No useful events in the log.";
    config_.begin_time_ = config_.end_time_ = Timestamp::Zero();
  }

  RTC_LOG(LS_INFO) << "Log is "
                   << (parsed_log_.last_timestamp().ms() -
                       parsed_log_.first_timestamp().ms()) /
                          1000
                   << " seconds long.";
}

EventLogAnalyzer::EventLogAnalyzer(const Environment& env,
                                   const ParsedRtcEventLog& log,
                                   const AnalyzerConfig& config)
    : env_(env), parsed_log_(log), config_(config) {
  RTC_LOG(LS_INFO) << "Log is "
                   << (parsed_log_.last_timestamp().ms() -
                       parsed_log_.first_timestamp().ms()) /
                          1000
                   << " seconds long.";
}

class BitrateObserver : public RemoteBitrateObserver {
 public:
  BitrateObserver() : last_bitrate_bps_(0), bitrate_updated_(false) {}

  void Update(NetworkControlUpdate update) {
    if (update.target_rate) {
      last_bitrate_bps_ = update.target_rate->target_rate.bps();
      bitrate_updated_ = true;
    }
  }

  void OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
                               uint32_t bitrate) override {}

  uint32_t last_bitrate_bps() const { return last_bitrate_bps_; }
  bool GetAndResetBitrateUpdated() {
    bool bitrate_updated = bitrate_updated_;
    bitrate_updated_ = false;
    return bitrate_updated;
  }

 private:
  uint32_t last_bitrate_bps_;
  bool bitrate_updated_;
};

void EventLogAnalyzer::InitializeMapOfNamedGraphs(bool show_detector_state,
                                                  bool show_alr_state,
                                                  bool show_link_capacity) {
  plots_.RegisterPlot("incoming_packet_sizes", [this](Plot* plot) {
    this->CreatePacketGraph(kIncomingPacket, plot);
  });

  plots_.RegisterPlot("outgoing_packet_sizes", [this](Plot* plot) {
    this->CreatePacketGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("incoming_rtcp_types", [this](Plot* plot) {
    this->CreateRtcpTypeGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("outgoing_rtcp_types", [this](Plot* plot) {
    this->CreateRtcpTypeGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("incoming_packet_count", [this](Plot* plot) {
    this->CreateAccumulatedPacketsGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("outgoing_packet_count", [this](Plot* plot) {
    this->CreateAccumulatedPacketsGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("incoming_packet_rate", [this](Plot* plot) {
    this->CreatePacketRateGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("outgoing_packet_rate", [this](Plot* plot) {
    this->CreatePacketRateGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("total_incoming_packet_rate", [this](Plot* plot) {
    this->CreateTotalPacketRateGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("total_outgoing_packet_rate", [this](Plot* plot) {
    this->CreateTotalPacketRateGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("audio_playout",
                      [this](Plot* plot) { this->CreatePlayoutGraph(plot); });

  plots_.RegisterPlot("neteq_set_minimum_delay", [this](Plot* plot) {
    this->CreateNetEqSetMinimumDelay(plot);
  });

  plots_.RegisterPlot("incoming_audio_level", [this](Plot* plot) {
    this->CreateAudioLevelGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("outgoing_audio_level", [this](Plot* plot) {
    this->CreateAudioLevelGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("incoming_sequence_number_delta", [this](Plot* plot) {
    this->CreateSequenceNumberGraph(plot);
  });
  plots_.RegisterPlot("incoming_delay", [this](Plot* plot) {
    this->CreateIncomingDelayGraph(plot);
  });
  plots_.RegisterPlot("incoming_loss_rate", [this](Plot* plot) {
    this->CreateIncomingPacketLossGraph(plot);
  });
  plots_.RegisterPlot("incoming_bitrate", [this](Plot* plot) {
    this->CreateTotalIncomingBitrateGraph(plot);
  });
  plots_.RegisterPlot(
      "outgoing_bitrate", [this, show_detector_state, show_alr_state,
                           show_link_capacity](Plot* plot) {
        this->CreateTotalOutgoingBitrateGraph(
            plot, show_detector_state, show_alr_state, show_link_capacity);
      });
  plots_.RegisterPlot("incoming_stream_bitrate", [this](Plot* plot) {
    this->CreateStreamBitrateGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("outgoing_stream_bitrate", [this](Plot* plot) {
    this->CreateStreamBitrateGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("incoming_layer_bitrate_allocation", [this](Plot* plot) {
    this->CreateBitrateAllocationGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("outgoing_layer_bitrate_allocation", [this](Plot* plot) {
    this->CreateBitrateAllocationGraph(kOutgoingPacket, plot);
  });
  plots_.RegisterPlot("simulated_receiveside_bwe", [this](Plot* plot) {
    this->CreateReceiveSideBweSimulationGraph(plot);
  });
  plots_.RegisterPlot("simulated_sendside_bwe", [this](Plot* plot) {
    this->CreateSendSideBweSimulationGraph(plot);
  });
  plots_.RegisterPlot("simulated_goog_cc", [this](Plot* plot) {
    this->CreateGoogCcSimulationGraph(plot);
  });
  plots_.RegisterPlot("outgoing_loss", [this](Plot* plot) {
    this->CreateOutgoingLossRateGraph(plot);
  });
  plots_.RegisterPlot("outgoing_twcc_loss", [this](Plot* plot) {
    this->CreateOutgoingLossRateGraph(plot);
  });
  plots_.RegisterPlot("outgoing_ecn_feedback", [this](Plot* plot) {
    this->CreateOutgoingEcnFeedbackGraph(plot);
  });
  plots_.RegisterPlot("incoming_ecn_feedback", [this](Plot* plot) {
    this->CreateIncomingEcnFeedbackGraph(plot);
  });
  plots_.RegisterPlot("network_delay_feedback", [this](Plot* plot) {
    this->CreateNetworkDelayFeedbackGraph(plot);
  });
  plots_.RegisterPlot("fraction_loss_feedback", [this](Plot* plot) {
    this->CreateFractionLossGraph(plot);
  });
  plots_.RegisterPlot("incoming_timestamps", [this](Plot* plot) {
    this->CreateTimestampGraph(kIncomingPacket, plot);
  });
  plots_.RegisterPlot("outgoing_timestamps", [this](Plot* plot) {
    this->CreateTimestampGraph(kOutgoingPacket, plot);
  });

  plots_.RegisterPlot("incoming_rtcp_fraction_lost", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(kIncomingPacket, GetFractionLost,
                                            "Fraction lost (incoming RTCP)",
                                            "Loss rate (percent)", plot);
  });
  plots_.RegisterPlot("outgoing_rtcp_fraction_lost", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(kOutgoingPacket, GetFractionLost,
                                            "Fraction lost (outgoing RTCP)",
                                            "Loss rate (percent)", plot);
  });

  plots_.RegisterPlot("incoming_rtcp_cumulative_lost", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(
        kIncomingPacket, GetCumulativeLost,
        "Cumulative lost packets (incoming RTCP)", "Packets", plot);
  });
  plots_.RegisterPlot("outgoing_rtcp_cumulative_lost", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(
        kOutgoingPacket, GetCumulativeLost,
        "Cumulative lost packets (outgoing RTCP)", "Packets", plot);
  });

  plots_.RegisterPlot("incoming_rtcp_highest_seq_number", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(
        kIncomingPacket, GetHighestSeqNumber,
        "Highest sequence number (incoming RTCP)", "Sequence number", plot);
  });
  plots_.RegisterPlot("outgoing_rtcp_highest_seq_number", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(
        kOutgoingPacket, GetHighestSeqNumber,
        "Highest sequence number (outgoing RTCP)", "Sequence number", plot);
  });

  plots_.RegisterPlot("incoming_rtcp_delay_since_last_sr", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(
        kIncomingPacket, DelaySinceLastSr,
        "Delay since last received sender report (incoming RTCP)", "Time (s)",
        plot);
  });
  plots_.RegisterPlot("outgoing_rtcp_delay_since_last_sr", [this](Plot* plot) {
    this->CreateSenderAndReceiverReportPlot(
        kOutgoingPacket, DelaySinceLastSr,
        "Delay since last received sender report (outgoing RTCP)", "Time (s)",
        plot);
  });

  plots_.RegisterPlot(
      "pacer_delay", [this](Plot* plot) { this->CreatePacerDelayGraph(plot); });

  plots_.RegisterPlot("audio_encoder_bitrate", [this](Plot* plot) {
    CreateAudioEncoderTargetBitrateGraph(this->parsed_log_, this->config_,
                                         plot);
  });
  plots_.RegisterPlot("audio_encoder_frame_length", [this](Plot* plot) {
    CreateAudioEncoderFrameLengthGraph(this->parsed_log_, this->config_, plot);
  });
  plots_.RegisterPlot("audio_encoder_packet_loss", [this](Plot* plot) {
    CreateAudioEncoderPacketLossGraph(this->parsed_log_, this->config_, plot);
  });
  plots_.RegisterPlot("audio_encoder_fec", [this](Plot* plot) {
    CreateAudioEncoderEnableFecGraph(this->parsed_log_, this->config_, plot);
  });
  plots_.RegisterPlot("audio_encoder_dtx", [this](Plot* plot) {
    CreateAudioEncoderEnableDtxGraph(this->parsed_log_, this->config_, plot);
  });
  plots_.RegisterPlot("audio_encoder_num_channels", [this](Plot* plot) {
    CreateAudioEncoderNumChannelsGraph(this->parsed_log_, this->config_, plot);
  });

  plots_.RegisterPlot("ice_candidate_pair_config", [this](Plot* plot) {
    this->CreateIceCandidatePairConfigGraph(plot);
  });
  plots_.RegisterPlot("ice_connectivity_check", [this](Plot* plot) {
    this->CreateIceConnectivityCheckGraph(plot);
  });
  plots_.RegisterPlot("dtls_transport_state", [this](Plot* plot) {
    this->CreateDtlsTransportStateGraph(plot);
  });
  plots_.RegisterPlot("dtls_writable_state", [this](Plot* plot) {
    this->CreateDtlsWritableStateGraph(plot);
  });
}

void EventLogAnalyzer::CreateGraphsByName(const std::vector<std::string>& names,
                                          PlotCollection* collection) const {
  for (absl::string_view name : names) {
    auto plot = absl::c_find_if(plots_, [name](const PlotDeclaration& plot) {
      return plot.label == name;
    });
    if (plot != plots_.end()) {
      Plot* output = collection->AppendNewPlot(plot->label);
      plot->plot_func(output);
    }
  }
}

void EventLogAnalyzer::CreatePacketGraph(PacketDirection direction,
                                         Plot* plot) const {
  for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) {
    // Filter on SSRC.
    if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) {
      continue;
    }

    TimeSeries time_series(GetStreamName(parsed_log_, direction, stream.ssrc),
                           LineStyle::kBar);
    auto GetPacketSize = [](const LoggedRtpPacket& packet) {
      return std::optional<float>(packet.total_length);
    };
    auto ToCallTime = [this](const LoggedRtpPacket& packet) {
      return this->config_.GetCallTimeSec(packet.timestamp);
    };
    ProcessPoints<LoggedRtpPacket>(ToCallTime, GetPacketSize,
                                   stream.packet_view, &time_series);
    plot->AppendTimeSeries(std::move(time_series));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Packet size (bytes)", kBottomMargin,
                          kTopMargin);
  plot->SetTitle(GetDirectionAsString(direction) + " RTP packets");
}

void EventLogAnalyzer::CreateRtcpTypeGraph(PacketDirection direction,
                                           Plot* plot) const {
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(
      parsed_log_.transport_feedbacks(direction), config_, "TWCC", 1));
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(
      parsed_log_.congestion_feedback(direction), config_, "CCFB", 2));
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(
      parsed_log_.receiver_reports(direction), config_, "RR", 3));
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(
      parsed_log_.sender_reports(direction), config_, "SR", 4));
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(
      parsed_log_.extended_reports(direction), config_, "XR", 5));
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(parsed_log_.nacks(direction),
                                                  config_, "NACK", 6));
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(parsed_log_.rembs(direction),
                                                  config_, "REMB", 7));
  plot->AppendTimeSeries(
      CreateRtcpTypeTimeSeries(parsed_log_.firs(direction), config_, "FIR", 8));
  plot->AppendTimeSeries(
      CreateRtcpTypeTimeSeries(parsed_log_.plis(direction), config_, "PLI", 9));
  plot->AppendTimeSeries(CreateRtcpTypeTimeSeries(parsed_log_.byes(direction),
                                                  config_, "BYE", 10));
  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "RTCP type", kBottomMargin, kTopMargin);
  plot->SetTitle(GetDirectionAsString(direction) + " RTCP packets");
  plot->SetYAxisTickLabels({{1, "TWCC"},
                            {2, "CCFB"},
                            {3, "RR"},
                            {4, "SR"},
                            {5, "XR"},
                            {6, "NACK"},
                            {7, "REMB"},
                            {8, "FIR"},
                            {9, "PLI"},
                            {10, "BYE"}});
}

template <typename IterableType>
void EventLogAnalyzer::CreateAccumulatedPacketsTimeSeries(
    Plot* plot,
    const IterableType& packets,
    const std::string& label) const {
  TimeSeries time_series(label, LineStyle::kStep);
  for (size_t i = 0; i < packets.size(); i++) {
    float x = config_.GetCallTimeSec(packets[i].log_time());
    time_series.points.emplace_back(x, i + 1);
  }
  plot->AppendTimeSeries(std::move(time_series));
}

void EventLogAnalyzer::CreateAccumulatedPacketsGraph(PacketDirection direction,
                                                     Plot* plot) const {
  for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) {
    if (!MatchingSsrc(stream.ssrc, desired_ssrc_))
      continue;
    std::string label = std::string("RTP ") +
                        GetStreamName(parsed_log_, direction, stream.ssrc);
    CreateAccumulatedPacketsTimeSeries(plot, stream.packet_view, label);
  }
  std::string label =
      std::string("RTCP ") + "(" + GetDirectionAsShortString(direction) + ")";
  if (direction == kIncomingPacket) {
    CreateAccumulatedPacketsTimeSeries(
        plot, parsed_log_.incoming_rtcp_packets(), label);
  } else {
    CreateAccumulatedPacketsTimeSeries(
        plot, parsed_log_.outgoing_rtcp_packets(), label);
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Received Packets", kBottomMargin, kTopMargin);
  plot->SetTitle(std::string("Accumulated ") + GetDirectionAsString(direction) +
                 " RTP/RTCP packets");
}

void EventLogAnalyzer::CreatePacketRateGraph(PacketDirection direction,
                                             Plot* plot) const {
  auto CountPackets = [](auto packet) { return 1.0; };
  for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) {
    // Filter on SSRC.
    if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) {
      continue;
    }
    TimeSeries time_series(
        std::string("RTP ") +
            GetStreamName(parsed_log_, direction, stream.ssrc),
        LineStyle::kLine);
    MovingAverage<LoggedRtpPacket, double>(CountPackets, stream.packet_view,
                                           config_, &time_series);
    plot->AppendTimeSeries(std::move(time_series));
  }
  TimeSeries time_series(
      std::string("RTCP ") + "(" + GetDirectionAsShortString(direction) + ")",
      LineStyle::kLine);
  if (direction == kIncomingPacket) {
    MovingAverage<LoggedRtcpPacketIncoming, double>(
        CountPackets, parsed_log_.incoming_rtcp_packets(), config_,
        &time_series);
  } else {
    MovingAverage<LoggedRtcpPacketOutgoing, double>(
        CountPackets, parsed_log_.outgoing_rtcp_packets(), config_,
        &time_series);
  }
  plot->AppendTimeSeries(std::move(time_series));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Packet Rate (packets/s)", kBottomMargin,
                          kTopMargin);
  plot->SetTitle("Rate of " + GetDirectionAsString(direction) +
                 " RTP/RTCP packets");
}

void EventLogAnalyzer::CreateTotalPacketRateGraph(PacketDirection direction,
                                                  Plot* plot) const {
  // Contains a log timestamp to enable counting logged events of different
  // types using MovingAverage().
  class LogTime {
   public:
    explicit LogTime(Timestamp log_time) : log_time_(log_time) {}
    Timestamp log_time() const { return log_time_; }

   private:
    Timestamp log_time_;
  };
  std::vector<LogTime> packet_times;
  auto handle_rtp = [&packet_times](const LoggedRtpPacket& packet) {
    packet_times.emplace_back(packet.log_time());
  };
  RtcEventProcessor process;
  for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) {
    process.AddEvents(stream.packet_view, handle_rtp, direction);
  }
  if (direction == kIncomingPacket) {
    auto handle_incoming_rtcp =
        [&packet_times](const LoggedRtcpPacketIncoming& packet) {
          packet_times.emplace_back(packet.log_time());
        };
    process.AddEvents(parsed_log_.incoming_rtcp_packets(),
                      handle_incoming_rtcp);
  } else {
    auto handle_outgoing_rtcp =
        [&packet_times](const LoggedRtcpPacketOutgoing& packet) {
          packet_times.emplace_back(packet.log_time());
        };
    process.AddEvents(parsed_log_.outgoing_rtcp_packets(),
                      handle_outgoing_rtcp);
  }
  process.ProcessEventsInOrder();
  TimeSeries time_series(std::string("Total ") + "(" +
                             GetDirectionAsShortString(direction) + ") packets",
                         LineStyle::kLine);
  MovingAverage<LogTime, uint64_t>([](auto packet) { return 1; }, packet_times,
                                   config_, &time_series);
  plot->AppendTimeSeries(std::move(time_series));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Packet Rate (packets/s)", kBottomMargin,
                          kTopMargin);
  plot->SetTitle("Rate of all " + GetDirectionAsString(direction) +
                 " RTP/RTCP packets");
}

// For each SSRC, plot the time between the consecutive playouts.
void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) const {
  for (const auto& playout_stream : parsed_log_.audio_playout_events()) {
    uint32_t ssrc = playout_stream.first;
    if (!MatchingSsrc(ssrc, desired_ssrc_))
      continue;
    std::optional<int64_t> last_playout_ms;
    TimeSeries time_series(SsrcToString(ssrc), LineStyle::kBar);
    for (const auto& playout_event : playout_stream.second) {
      float x = config_.GetCallTimeSec(playout_event.log_time());
      int64_t playout_time_ms = playout_event.log_time_ms();
      // If there were no previous playouts, place the point on the x-axis.
      float y = playout_time_ms - last_playout_ms.value_or(playout_time_ms);
      time_series.points.push_back(TimeSeriesPoint(x, y));
      last_playout_ms.emplace(playout_time_ms);
    }
    plot->AppendTimeSeries(std::move(time_series));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Time since last playout (ms)", kBottomMargin,
                          kTopMargin);
  plot->SetTitle("Audio playout");
}

void EventLogAnalyzer::CreateNetEqSetMinimumDelay(Plot* plot) const {
  for (const auto& playout_stream :
       parsed_log_.neteq_set_minimum_delay_events()) {
    uint32_t ssrc = playout_stream.first;
    if (!MatchingSsrc(ssrc, desired_ssrc_))
      continue;

    TimeSeries time_series(SsrcToString(ssrc), LineStyle::kStep,
                           PointStyle::kHighlight);
    for (const auto& event : playout_stream.second) {
      float x = config_.GetCallTimeSec(event.log_time());
      float y = event.minimum_delay_ms;
      time_series.points.push_back(TimeSeriesPoint(x, y));
    }
    plot->AppendTimeSeries(std::move(time_series));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1000, "Minimum Delay (ms)", kBottomMargin,
                          kTopMargin);
  plot->SetTitle("Set Minimum Delay");
}

// For audio SSRCs, plot the audio level.
void EventLogAnalyzer::CreateAudioLevelGraph(PacketDirection direction,
                                             Plot* plot) const {
  for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) {
    if (!IsAudioSsrc(parsed_log_, direction, stream.ssrc))
      continue;
    TimeSeries time_series(GetStreamName(parsed_log_, direction, stream.ssrc),
                           LineStyle::kLine);
    for (auto& packet : stream.packet_view) {
      if (packet.header.extension.audio_level()) {
        float x = config_.GetCallTimeSec(packet.log_time());
        // The audio level is stored in -dBov (so e.g. -10 dBov is stored as 10)
        // Here we convert it to dBov.
        float y =
            static_cast<float>(-packet.header.extension.audio_level()->level());
        time_series.points.emplace_back(TimeSeriesPoint(x, y));
      }
    }
    plot->AppendTimeSeries(std::move(time_series));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetYAxis(-127, 0, "Audio level (dBov)", kBottomMargin, kTopMargin);
  plot->SetTitle(GetDirectionAsString(direction) + " audio level");
}

// For each SSRC, plot the sequence number difference between consecutive
// incoming packets.
void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) const {
  for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) {
    // Filter on SSRC.
    if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) {
      continue;
    }

    TimeSeries time_series(
        GetStreamName(parsed_log_, kIncomingPacket, stream.ssrc),
        LineStyle::kBar);
    auto GetSequenceNumberDiff = [](const LoggedRtpPacketIncoming& old_packet,
                                    const LoggedRtpPacketIncoming& new_packet) {
      int64_t diff =
          WrappingDifference(new_packet.rtp.header.sequenceNumber,
                             old_packet.rtp.header.sequenceNumber, 1ul << 16);
      return diff;
    };
    auto ToCallTime = [this](const LoggedRtpPacketIncoming& packet) {
      return this->config_.GetCallTimeSec(packet.log_time());
    };
    ProcessPairs<LoggedRtpPacketIncoming, float>(
        ToCallTime, GetSequenceNumberDiff, stream.incoming_packets,
        &time_series);
    plot->AppendTimeSeries(std::move(time_series));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Difference since last packet", kBottomMargin,
                          kTopMargin);
  plot->SetTitle("Incoming sequence number delta");
}

void EventLogAnalyzer::CreateIncomingPacketLossGraph(Plot* plot) const {
  for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) {
    const std::vector<LoggedRtpPacketIncoming>& packets =
        stream.incoming_packets;
    // Filter on SSRC.
    if (!MatchingSsrc(stream.ssrc, desired_ssrc_) || packets.empty()) {
      continue;
    }

    TimeSeries time_series(
        GetStreamName(parsed_log_, kIncomingPacket, stream.ssrc),
        LineStyle::kLine, PointStyle::kHighlight);
    // TODO(terelius): Should the window and step size be read from the class
    // instead?
    const TimeDelta kWindow = TimeDelta::Millis(1000);
    const TimeDelta kStep = TimeDelta::Millis(1000);
    SeqNumUnwrapper<uint16_t> unwrapper_;
    SeqNumUnwrapper<uint16_t> prior_unwrapper_;
    size_t window_index_begin = 0;
    size_t window_index_end = 0;
    uint64_t highest_seq_number =
        unwrapper_.Unwrap(packets[0].rtp.header.sequenceNumber) - 1;
    uint64_t highest_prior_seq_number =
        prior_unwrapper_.Unwrap(packets[0].rtp.header.sequenceNumber) - 1;

    for (Timestamp t = config_.begin_time_; t < config_.end_time_ + kStep;
         t += kStep) {
      while (window_index_end < packets.size() &&
             packets[window_index_end].rtp.log_time() < t) {
        uint64_t sequence_number = unwrapper_.Unwrap(
            packets[window_index_end].rtp.header.sequenceNumber);
        highest_seq_number = std::max(highest_seq_number, sequence_number);
        ++window_index_end;
      }
      while (window_index_begin < packets.size() &&
             packets[window_index_begin].rtp.log_time() < t - kWindow) {
        uint64_t sequence_number = prior_unwrapper_.Unwrap(
            packets[window_index_begin].rtp.header.sequenceNumber);
        highest_prior_seq_number =
            std::max(highest_prior_seq_number, sequence_number);
        ++window_index_begin;
      }
      float x = config_.GetCallTimeSec(t);
      uint64_t expected_packets = highest_seq_number - highest_prior_seq_number;
      if (expected_packets > 0) {
        int64_t received_packets = window_index_end - window_index_begin;
        int64_t lost_packets = expected_packets - received_packets;
        float y = static_cast<float>(lost_packets) / expected_packets * 100;
        time_series.points.emplace_back(x, y);
      }
    }
    plot->AppendTimeSeries(std::move(time_series));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Loss rate (in %)", kBottomMargin, kTopMargin);
  plot->SetTitle("Incoming packet loss (derived from incoming packets)");
}

void EventLogAnalyzer::CreateIncomingDelayGraph(Plot* plot) const {
  for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) {
    // Filter on SSRC.
    if (!MatchingSsrc(stream.ssrc, desired_ssrc_) ||
        IsRtxSsrc(parsed_log_, kIncomingPacket, stream.ssrc)) {
      continue;
    }

    const std::vector<LoggedRtpPacketIncoming>& packets =
        stream.incoming_packets;
    if (packets.size() < 100) {
      RTC_LOG(LS_WARNING) << "Can't estimate the RTP clock frequency with "
                          << packets.size() << " packets in the stream.";
      continue;
    }
    int64_t segment_end_us = parsed_log_.first_log_segment().stop_time_us();
    std::optional<uint32_t> estimated_frequency =
        EstimateRtpClockFrequency(packets, segment_end_us);
    if (!estimated_frequency)
      continue;
    const double frequency_hz = *estimated_frequency;
    if (IsVideoSsrc(parsed_log_, kIncomingPacket, stream.ssrc) &&
        frequency_hz != 90000) {
      RTC_LOG(LS_WARNING)
          << "Video stream should use a 90 kHz clock but appears to use "
          << frequency_hz / 1000 << ". Discarding.";
      continue;
    }

    auto ToCallTime = [this](const LoggedRtpPacketIncoming& packet) {
      return this->config_.GetCallTimeSec(packet.log_time());
    };
    auto ToNetworkDelay = [frequency_hz](
                              const LoggedRtpPacketIncoming& old_packet,
                              const LoggedRtpPacketIncoming& new_packet) {
      return NetworkDelayDiff_CaptureTime(old_packet, new_packet, frequency_hz);
    };

    TimeSeries capture_time_data(
        GetStreamName(parsed_log_, kIncomingPacket, stream.ssrc) +
            " capture-time",
        LineStyle::kLine);
    AccumulatePairs<LoggedRtpPacketIncoming, double>(
        ToCallTime, ToNetworkDelay, packets, &capture_time_data);
    plot->AppendTimeSeries(std::move(capture_time_data));

    TimeSeries send_time_data(
        GetStreamName(parsed_log_, kIncomingPacket, stream.ssrc) +
            " abs-send-time",
        LineStyle::kLine);
    AccumulatePairs<LoggedRtpPacketIncoming, double>(
        ToCallTime, NetworkDelayDiff_AbsSendTime, packets, &send_time_data);
    plot->AppendTimeSeriesIfNotEmpty(std::move(send_time_data));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Delay (ms)", kBottomMargin, kTopMargin);
  plot->SetTitle("Incoming network delay (relative to first packet)");
}

// Plot the fraction of packets lost (as perceived by the loss-based BWE).
void EventLogAnalyzer::CreateFractionLossGraph(Plot* plot) const {
  TimeSeries time_series("Fraction lost", LineStyle::kLine,
                         PointStyle::kHighlight);
  for (auto& bwe_update : parsed_log_.bwe_loss_updates()) {
    float x = config_.GetCallTimeSec(bwe_update.log_time());
    float y = static_cast<float>(bwe_update.fraction_lost) / 255 * 100;
    time_series.points.emplace_back(x, y);
  }

  plot->AppendTimeSeries(std::move(time_series));
  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 10, "Loss rate (in %)", kBottomMargin, kTopMargin);
  plot->SetTitle("Outgoing packet loss (as reported by BWE)");
}

// Plot the total bandwidth used by all RTP streams.
void EventLogAnalyzer::CreateTotalIncomingBitrateGraph(Plot* plot) const {
  // TODO(terelius): This could be provided by the parser.
  std::multimap<Timestamp, size_t> packets_in_order;
  for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) {
    for (const LoggedRtpPacketIncoming& packet : stream.incoming_packets)
      packets_in_order.insert(
          std::make_pair(packet.rtp.log_time(), packet.rtp.total_length));
  }

  auto window_begin = packets_in_order.begin();
  auto window_end = packets_in_order.begin();
  size_t bytes_in_window = 0;

  if (!packets_in_order.empty()) {
    // Calculate a moving average of the bitrate and store in a TimeSeries.
    TimeSeries bitrate_series("Bitrate", LineStyle::kLine);
    for (Timestamp 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_.us()) /
          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));
  }

  // Overlay the outgoing REMB over incoming bitrate.
  TimeSeries remb_series("Remb", LineStyle::kStep);
  for (const auto& rtcp : parsed_log_.rembs(kOutgoingPacket)) {
    float x = config_.GetCallTimeSec(rtcp.log_time());
    float y = static_cast<float>(rtcp.remb.bitrate_bps()) / 1000;
    remb_series.points.emplace_back(x, y);
  }
  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);
  plot->SetTitle("Incoming RTP bitrate");
}

// Plot the total bandwidth used by all RTP streams.
void EventLogAnalyzer::CreateTotalOutgoingBitrateGraph(
    Plot* plot,
    bool show_detector_state,
    bool show_alr_state,
    bool show_link_capacity) const {
  // TODO(terelius): This could be provided by the parser.
  std::multimap<Timestamp, size_t> packets_in_order;
  for (const auto& stream : parsed_log_.outgoing_rtp_packets_by_ssrc()) {
    for (const LoggedRtpPacketOutgoing& packet : stream.outgoing_packets)
      packets_in_order.insert(
          std::make_pair(packet.rtp.log_time(), packet.rtp.total_length));
  }

  auto window_begin = packets_in_order.begin();
  auto window_end = packets_in_order.begin();
  size_t bytes_in_window = 0;

  if (!packets_in_order.empty()) {
    // Calculate a moving average of the bitrate and store in a TimeSeries.
    TimeSeries bitrate_series("Bitrate", LineStyle::kLine);
    for (Timestamp 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_.us()) /
          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));
  }

  // Overlay the send-side bandwidth estimate over the outgoing bitrate.
  TimeSeries loss_series("Loss-based estimate", LineStyle::kStep);
  for (auto& loss_update : parsed_log_.bwe_loss_updates()) {
    float x = config_.GetCallTimeSec(loss_update.log_time());
    float y = static_cast<float>(loss_update.bitrate_bps) / 1000;
    loss_series.points.emplace_back(x, y);
  }

  TimeSeries link_capacity_lower_series("Link-capacity-lower",
                                        LineStyle::kStep);
  TimeSeries link_capacity_upper_series("Link-capacity-upper",
                                        LineStyle::kStep);
  for (auto& remote_estimate_event : parsed_log_.remote_estimate_events()) {
    float x = config_.GetCallTimeSec(remote_estimate_event.log_time());
    if (remote_estimate_event.link_capacity_lower.has_value()) {
      float link_capacity_lower = static_cast<float>(
          remote_estimate_event.link_capacity_lower.value().kbps());
      link_capacity_lower_series.points.emplace_back(x, link_capacity_lower);
    }
    if (remote_estimate_event.link_capacity_upper.has_value()) {
      float link_capacity_upper = static_cast<float>(
          remote_estimate_event.link_capacity_upper.value().kbps());
      link_capacity_upper_series.points.emplace_back(x, link_capacity_upper);
    }
  }

  TimeSeries delay_series("Delay-based estimate", LineStyle::kStep);
  IntervalSeries overusing_series("Overusing", "#ff8e82",
                                  IntervalSeries::kHorizontal);
  IntervalSeries underusing_series("Underusing", "#5092fc",
                                   IntervalSeries::kHorizontal);
  IntervalSeries normal_series("Normal", "#c4ffc4",
                               IntervalSeries::kHorizontal);
  IntervalSeries* last_series = &normal_series;
  float last_detector_switch = 0.0;

  BandwidthUsage last_detector_state = BandwidthUsage::kBwNormal;

  for (auto& delay_update : parsed_log_.bwe_delay_updates()) {
    float x = config_.GetCallTimeSec(delay_update.log_time());
    float y = static_cast<float>(delay_update.bitrate_bps) / 1000;

    if (last_detector_state != delay_update.detector_state) {
      last_series->intervals.emplace_back(last_detector_switch, x);
      last_detector_state = delay_update.detector_state;
      last_detector_switch = x;

      switch (delay_update.detector_state) {
        case BandwidthUsage::kBwNormal:
          last_series = &normal_series;
          break;
        case BandwidthUsage::kBwUnderusing:
          last_series = &underusing_series;
          break;
        case BandwidthUsage::kBwOverusing:
          last_series = &overusing_series;
          break;
        case BandwidthUsage::kLast:
          RTC_DCHECK_NOTREACHED();
      }
    }

    delay_series.points.emplace_back(x, y);
  }

  RTC_CHECK(last_series);
  last_series->intervals.emplace_back(last_detector_switch,
                                      config_.CallEndTimeSec());

  TimeSeries created_series("Probe cluster created.", LineStyle::kNone,
                            PointStyle::kHighlight);
  for (auto& cluster : parsed_log_.bwe_probe_cluster_created_events()) {
    float x = config_.GetCallTimeSec(cluster.log_time());
    float y = static_cast<float>(cluster.bitrate_bps) / 1000;
    created_series.points.emplace_back(x, y);
  }

  TimeSeries result_series("Probing results.", LineStyle::kNone,
                           PointStyle::kHighlight);
  for (auto& result : parsed_log_.bwe_probe_success_events()) {
    float x = config_.GetCallTimeSec(result.log_time());
    float y = static_cast<float>(result.bitrate_bps) / 1000;
    result_series.points.emplace_back(x, y);
  }

  TimeSeries probe_failures_series("Probe failed", LineStyle::kNone,
                                   PointStyle::kHighlight);
  for (auto& failure : parsed_log_.bwe_probe_failure_events()) {
    float x = config_.GetCallTimeSec(failure.log_time());
    probe_failures_series.points.emplace_back(x, 0);
  }

  IntervalSeries alr_state("ALR", "#555555", IntervalSeries::kHorizontal);
  bool previously_in_alr = false;
  Timestamp alr_start = Timestamp::Zero();
  for (auto& alr : parsed_log_.alr_state_events()) {
    float y = config_.GetCallTimeSec(alr.log_time());
    if (!previously_in_alr && alr.in_alr) {
      alr_start = alr.log_time();
      previously_in_alr = true;
    } else if (previously_in_alr && !alr.in_alr) {
      float x = config_.GetCallTimeSec(alr_start);
      alr_state.intervals.emplace_back(x, y);
      previously_in_alr = false;
    }
  }

  if (previously_in_alr) {
    float x = config_.GetCallTimeSec(alr_start);
    float y = config_.GetCallTimeSec(config_.end_time_);
    alr_state.intervals.emplace_back(x, y);
  }

  if (show_detector_state) {
    plot->AppendIntervalSeries(std::move(overusing_series));
    plot->AppendIntervalSeries(std::move(underusing_series));
    plot->AppendIntervalSeries(std::move(normal_series));
  }

  if (show_alr_state) {
    plot->AppendIntervalSeries(std::move(alr_state));
  }

  if (show_link_capacity) {
    plot->AppendTimeSeriesIfNotEmpty(std::move(link_capacity_lower_series));
    plot->AppendTimeSeriesIfNotEmpty(std::move(link_capacity_upper_series));
  }

  plot->AppendTimeSeries(std::move(loss_series));
  plot->AppendTimeSeriesIfNotEmpty(std::move(probe_failures_series));
  plot->AppendTimeSeries(std::move(delay_series));
  plot->AppendTimeSeries(std::move(created_series));
  plot->AppendTimeSeries(std::move(result_series));

  // Overlay the incoming REMB over the outgoing bitrate.
  TimeSeries remb_series("Remb", LineStyle::kStep);
  for (const auto& rtcp : parsed_log_.rembs(kIncomingPacket)) {
    float x = config_.GetCallTimeSec(rtcp.log_time());
    float y = static_cast<float>(rtcp.remb.bitrate_bps()) / 1000;
    remb_series.points.emplace_back(x, y);
  }
  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);
  plot->SetTitle("Outgoing RTP bitrate");
}

// For each SSRC, plot the bandwidth used by that stream.
void EventLogAnalyzer::CreateStreamBitrateGraph(PacketDirection direction,
                                                Plot* plot) const {
  for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) {
    // Filter on SSRC.
    if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) {
      continue;
    }

    TimeSeries time_series(GetStreamName(parsed_log_, direction, stream.ssrc),
                           LineStyle::kLine);
    auto GetPacketSizeKilobits = [](const LoggedRtpPacket& packet) {
      return packet.total_length * 8.0 / 1000.0;
    };
    MovingAverage<LoggedRtpPacket, double>(
        GetPacketSizeKilobits, stream.packet_view, 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);
  plot->SetTitle(GetDirectionAsString(direction) + " bitrate per stream");
}

// Plot the bitrate allocation for each temporal and spatial layer.
// Computed from RTCP XR target bitrate block, so the graph is only populated if
// those are sent.
void EventLogAnalyzer::CreateBitrateAllocationGraph(PacketDirection direction,
                                                    Plot* plot) const {
  std::map<LayerDescription, TimeSeries> time_series;
  const auto& xr_list = parsed_log_.extended_reports(direction);
  for (const auto& rtcp : xr_list) {
    const std::optional<rtcp::TargetBitrate>& target_bitrate =
        rtcp.xr.target_bitrate();
    if (!target_bitrate.has_value())
      continue;
    for (const auto& bitrate_item : target_bitrate->GetTargetBitrates()) {
      LayerDescription layer(rtcp.xr.sender_ssrc(), bitrate_item.spatial_layer,
                             bitrate_item.temporal_layer);
      auto time_series_it = time_series.find(layer);
      if (time_series_it == time_series.end()) {
        std::string layer_name = GetLayerName(layer);
        bool inserted;
        std::tie(time_series_it, inserted) = time_series.insert(
            std::make_pair(layer, TimeSeries(layer_name, LineStyle::kStep)));
        RTC_DCHECK(inserted);
      }
      float x = config_.GetCallTimeSec(rtcp.log_time());
      float y = bitrate_item.target_bitrate_kbps;
      time_series_it->second.points.emplace_back(x, y);
    }
  }
  for (auto& layer : time_series) {
    plot->AppendTimeSeries(std::move(layer.second));
  }
  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
  if (direction == kIncomingPacket)
    plot->SetTitle("Target bitrate per incoming layer");
  else
    plot->SetTitle("Target bitrate per outgoing layer");
}

void EventLogAnalyzer::CreateGoogCcSimulationGraph(Plot* plot) const {
  TimeSeries target_rates("Simulated target rate", LineStyle::kStep,
                          PointStyle::kHighlight);
  TimeSeries delay_based("Logged delay-based estimate", LineStyle::kStep,
                         PointStyle::kHighlight);
  TimeSeries loss_based("Logged loss-based estimate", LineStyle::kStep,
                        PointStyle::kHighlight);
  TimeSeries probe_results("Logged probe success", LineStyle::kNone,
                           PointStyle::kHighlight);

  LogBasedNetworkControllerSimulation simulation(
      env_, std::make_unique<GoogCcNetworkControllerFactory>(),
      [&](const NetworkControlUpdate& update, Timestamp at_time) {
        if (update.target_rate) {
          target_rates.points.emplace_back(
              config_.GetCallTimeSec(at_time),
              update.target_rate->target_rate.kbps<float>());
        }
      });

  simulation.ProcessEventsInLog(parsed_log_);
  for (const auto& logged : parsed_log_.bwe_delay_updates())
    delay_based.points.emplace_back(config_.GetCallTimeSec(logged.log_time()),
                                    logged.bitrate_bps / 1000);
  for (const auto& logged : parsed_log_.bwe_probe_success_events())
    probe_results.points.emplace_back(config_.GetCallTimeSec(logged.log_time()),
                                      logged.bitrate_bps / 1000);
  for (const auto& logged : parsed_log_.bwe_loss_updates())
    loss_based.points.emplace_back(config_.GetCallTimeSec(logged.log_time()),
                                   logged.bitrate_bps / 1000);

  plot->AppendTimeSeries(std::move(delay_based));
  plot->AppendTimeSeries(std::move(loss_based));
  plot->AppendTimeSeries(std::move(probe_results));
  plot->AppendTimeSeries(std::move(target_rates));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin);
  plot->SetTitle("Simulated BWE behavior");
}

void EventLogAnalyzer::CreateOutgoingEcnFeedbackGraph(Plot* plot) const {
  CreateEcnFeedbackGraph(plot, kOutgoingPacket);
  plot->SetTitle("Outgoing ECN count per feedback");
}

void EventLogAnalyzer::CreateIncomingEcnFeedbackGraph(Plot* plot) const {
  CreateEcnFeedbackGraph(plot, kIncomingPacket);
  plot->SetTitle("Incoming ECN count per feedback");
}

void EventLogAnalyzer::CreateEcnFeedbackGraph(Plot* plot,
                                              PacketDirection direction) const {
  TimeSeries not_ect("Not ECN capable", LineStyle::kBar,
                     PointStyle::kHighlight);
  TimeSeries ect_1("ECN capable", LineStyle::kBar, PointStyle::kHighlight);
  TimeSeries ce("Congestion experienced", LineStyle::kBar,
                PointStyle::kHighlight);

  for (const LoggedRtcpCongestionControlFeedback& feedback :
       parsed_log_.congestion_feedback(direction)) {
    int ect_1_count = 0;
    int not_ect_count = 0;
    int ce_count = 0;

    for (const rtcp::CongestionControlFeedback::PacketInfo& info :
         feedback.congestion_feedback.packets()) {
      switch (info.ecn) {
        case EcnMarking::kNotEct:
          ++not_ect_count;
          break;
        case EcnMarking::kEct1:
          ++ect_1_count;
          break;
        case EcnMarking::kEct0:
          RTC_LOG(LS_ERROR) << "unexpected ect(0)";
          break;
        case EcnMarking::kCe:
          ++ce_count;
          break;
      }
    }
    ect_1.points.emplace_back(config_.GetCallTimeSec(feedback.timestamp),
                              ect_1_count);
    not_ect.points.emplace_back(config_.GetCallTimeSec(feedback.timestamp),
                                not_ect_count);
    ce.points.emplace_back(config_.GetCallTimeSec(feedback.timestamp),
                           ce_count);
  }

  plot->AppendTimeSeriesIfNotEmpty(std::move(ect_1));
  plot->AppendTimeSeriesIfNotEmpty(std::move(not_ect));
  plot->AppendTimeSeriesIfNotEmpty(std::move(ce));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 10, "Count per feedback", kBottomMargin,
                          kTopMargin);
}

void EventLogAnalyzer::CreateOutgoingLossRateGraph(Plot* plot) const {
  struct PacketLossPerFeedback {
    Timestamp timestamp;              // Time when this feedback was received.
    int num_packets_in_feedback = 0;  // Includes lost packets.
    int num_lost_packets = 0;         // In this specific feedback.
    int num_reordered_packets = 0;    // Packets received in this feedback, but
                                      // was previously reported as lost.
    int num_missing_feedback =
        0;  // Packets missing feedback between this report and the previous.
  };

  class LossFeedbackBuilder {
   public:
    void AddPacket(uint16_t sequence_number, TimeDelta arrival_time_delta) {
      last_unwrapped_sequence_number_ =
          sequence_number_unwrapper_.Unwrap(sequence_number);
      if (!first_sequence_number_.has_value()) {
        first_sequence_number_ = last_unwrapped_sequence_number_;
      }
      ++num_packets_;
      if (arrival_time_delta.IsInfinite()) {
        lost_sequence_numbers_.insert(last_unwrapped_sequence_number_);
      } else {
        num_reordered_packets_ += previous_lost_sequence_numbers_.count(
            last_unwrapped_sequence_number_);
      }
    }

    void Update(PacketLossPerFeedback& feedback) {
      feedback.num_packets_in_feedback += num_packets_;
      feedback.num_lost_packets += lost_sequence_numbers_.size();
      feedback.num_reordered_packets += num_reordered_packets_;
      if (first_sequence_number_.has_value() &&
          previous_feedback_highest_seq_number_.has_value()) {
        feedback.num_missing_feedback +=
            *first_sequence_number_ - *previous_feedback_highest_seq_number_ -
            1;
      }

      // Prepare for next feedback.
      first_sequence_number_ = std::nullopt;
      previous_lost_sequence_numbers_.insert(lost_sequence_numbers_.begin(),
                                             lost_sequence_numbers_.end());
      previous_feedback_highest_seq_number_ = last_unwrapped_sequence_number_;
      lost_sequence_numbers_.clear();
      num_reordered_packets_ = 0;
      num_packets_ = 0;
    }

   private:
    int64_t last_unwrapped_sequence_number_ = 0;
    int num_reordered_packets_ = 0;
    int num_packets_ = 0;
    std::optional<int64_t> first_sequence_number_;

    std::unordered_set<int64_t> lost_sequence_numbers_;
    std::unordered_set<int64_t> previous_lost_sequence_numbers_;
    std::optional<int64_t> previous_feedback_highest_seq_number_;

    RtpSequenceNumberUnwrapper sequence_number_unwrapper_;
  };

  TimeSeries loss_rate_series("Loss rate (from packet feedback)",
                              LineStyle::kLine, PointStyle::kHighlight);
  TimeSeries reordered_packets_between_feedback(
      "Ratio of reordered packets from last feedback", LineStyle::kLine,
      PointStyle::kHighlight);
  TimeSeries average_loss_rate_series("Average loss rate last 5s",
                                      LineStyle::kLine, PointStyle::kHighlight);
  TimeSeries missing_feedback_series("Missing feedback", LineStyle::kNone,
                                     PointStyle::kHighlight);

  std::vector<PacketLossPerFeedback> loss_per_feedback;

  if (!parsed_log_.congestion_feedback(kIncomingPacket).empty()) {
    plot->SetTitle("Outgoing loss rate (from CCFB)");

    std::map</*ssrc*/ uint32_t, LossFeedbackBuilder> per_ssrc_builder;
    for (const LoggedRtcpCongestionControlFeedback& feedback :
         parsed_log_.congestion_feedback(kIncomingPacket)) {
      const rtcp::CongestionControlFeedback& transport_feedback =
          feedback.congestion_feedback;

      PacketLossPerFeedback packet_loss_per_feedback = {
          .timestamp = feedback.log_time()};
      for (const rtcp::CongestionControlFeedback::PacketInfo& packet :
           transport_feedback.packets()) {
        per_ssrc_builder[packet.ssrc].AddPacket(packet.sequence_number,
                                                packet.arrival_time_offset);
      }
      for (auto& [ssrc, builder] : per_ssrc_builder) {
        builder.Update(packet_loss_per_feedback);
      }
      loss_per_feedback.push_back(packet_loss_per_feedback);
    }
  } else if (!parsed_log_.transport_feedbacks(kIncomingPacket).empty()) {
    plot->SetTitle("Outgoing loss rate (from TWCC)");

    LossFeedbackBuilder builder;
    for (const LoggedRtcpPacketTransportFeedback& feedback :
         parsed_log_.transport_feedbacks(kIncomingPacket)) {
      feedback.transport_feedback.ForAllPackets(
          [&](uint16_t sequence_number, TimeDelta receive_time_delta) {
            builder.AddPacket(sequence_number, receive_time_delta);
          });
      PacketLossPerFeedback packet_loss_per_feedback = {
          .timestamp = feedback.log_time()};
      builder.Update(packet_loss_per_feedback);
      loss_per_feedback.push_back(packet_loss_per_feedback);
    }
  }

  PacketLossSummary window_summary;
  Timestamp last_observation_receive_time = Timestamp::Zero();

  // Use loss based bwe 2 observation duration and observation window size.
  constexpr TimeDelta kObservationDuration = TimeDelta::Millis(250);
  constexpr uint32_t kObservationWindowSize = 20;
  std::deque<PacketLossSummary> observations;
  int previous_feedback_size = 0;
  for (const PacketLossPerFeedback& feedback : loss_per_feedback) {
    for (int64_t num = 0; num < feedback.num_missing_feedback; ++num) {
      missing_feedback_series.points.emplace_back(
          config_.GetCallTimeSec(feedback.timestamp), 100 + num);
    }

    // Compute loss rate from the transport feedback.
    float loss_rate = static_cast<float>(feedback.num_lost_packets * 100.0 /
                                         feedback.num_packets_in_feedback);

    loss_rate_series.points.emplace_back(
        config_.GetCallTimeSec(feedback.timestamp), loss_rate);
    float reordered_rate =
        previous_feedback_size == 0
            ? 0
            : static_cast<float>(feedback.num_reordered_packets * 100.0 /
                                 previous_feedback_size);
    previous_feedback_size = feedback.num_packets_in_feedback;
    reordered_packets_between_feedback.points.emplace_back(
        config_.GetCallTimeSec(feedback.timestamp), reordered_rate);

    // Compute loss rate in a window of kObservationWindowSize.
    if (window_summary.num_packets == 0) {
      window_summary.base_time = feedback.timestamp;
    }
    window_summary.num_packets += feedback.num_packets_in_feedback;
    window_summary.num_lost_packets +=
        feedback.num_lost_packets - feedback.num_reordered_packets;

    const Timestamp last_received_time = feedback.timestamp;
    const TimeDelta observation_duration =
        window_summary.base_time == Timestamp::Zero()
            ? TimeDelta::Zero()
            : last_received_time - window_summary.base_time;
    if (observation_duration > kObservationDuration) {
      last_observation_receive_time = last_received_time;
      observations.push_back(window_summary);
      if (observations.size() > kObservationWindowSize) {
        observations.pop_front();
      }

      // Compute average loss rate in a number of windows.
      int total_packets = 0;
      int total_loss = 0;
      for (const auto& observation : observations) {
        total_loss += observation.num_lost_packets;
        total_packets += observation.num_packets;
      }
      if (total_packets > 0) {
        float average_loss_rate = total_loss * 100.0 / total_packets;
        average_loss_rate_series.points.emplace_back(
            config_.GetCallTimeSec(feedback.timestamp), average_loss_rate);
      } else {
        average_loss_rate_series.points.emplace_back(
            config_.GetCallTimeSec(feedback.timestamp), 0);
      }
      window_summary = PacketLossSummary();
    }
  }
  // Add the data set to the plot.
  plot->AppendTimeSeriesIfNotEmpty(std::move(loss_rate_series));
  plot->AppendTimeSeriesIfNotEmpty(
      std::move(reordered_packets_between_feedback));
  plot->AppendTimeSeriesIfNotEmpty(std::move(average_loss_rate_series));
  plot->AppendTimeSeriesIfNotEmpty(std::move(missing_feedback_series));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 100, "Loss rate (percent)", kBottomMargin,
                          kTopMargin);
}

void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) const {
  using RtpPacketType = LoggedRtpPacketOutgoing;
  using TransportFeedbackType = LoggedRtcpPacketTransportFeedback;

  // TODO(terelius): This could be provided by the parser.
  std::multimap<int64_t, const RtpPacketType*> outgoing_rtp;
  for (const auto& stream : parsed_log_.outgoing_rtp_packets_by_ssrc()) {
    for (const RtpPacketType& rtp_packet : stream.outgoing_packets)
      outgoing_rtp.insert(
          std::make_pair(rtp_packet.rtp.log_time_us(), &rtp_packet));
  }

  const std::vector<TransportFeedbackType>& incoming_rtcp =
      parsed_log_.transport_feedbacks(kIncomingPacket);

  SimulatedClock clock(0);
  BitrateObserver observer;
  TransportFeedbackAdapter transport_feedback;
  auto factory = GoogCcNetworkControllerFactory();
  TimeDelta process_interval = factory.GetProcessInterval();
  // TODO(holmer): Log the call config and use that here instead.
  static const uint32_t kDefaultStartBitrateBps = 300000;
  NetworkControllerConfig cc_config(env_);
  cc_config.constraints.at_time = clock.CurrentTime();
  cc_config.constraints.starting_rate =
      DataRate::BitsPerSec(kDefaultStartBitrateBps);
  auto goog_cc = factory.Create(cc_config);

  TimeSeries time_series("Delay-based estimate", LineStyle::kStep,
                         PointStyle::kHighlight);
  TimeSeries acked_time_series("Raw acked bitrate", LineStyle::kLine,
                               PointStyle::kHighlight);
  TimeSeries robust_time_series("Robust throughput estimate", LineStyle::kLine,
                                PointStyle::kHighlight);
  TimeSeries acked_estimate_time_series("Ackednowledged bitrate estimate",
                                        LineStyle::kLine,
                                        PointStyle::kHighlight);

  auto rtp_iterator = outgoing_rtp.begin();
  auto rtcp_iterator = incoming_rtcp.begin();

  auto NextRtpTime = [&]() {
    if (rtp_iterator != outgoing_rtp.end())
      return static_cast<int64_t>(rtp_iterator->first);
    return std::numeric_limits<int64_t>::max();
  };

  auto NextRtcpTime = [&]() {
    if (rtcp_iterator != incoming_rtcp.end())
      return static_cast<int64_t>(rtcp_iterator->log_time_us());
    return std::numeric_limits<int64_t>::max();
  };
  int64_t next_process_time_us_ = std::min({NextRtpTime(), NextRtcpTime()});

  auto NextProcessTime = [&]() {
    if (rtcp_iterator != incoming_rtcp.end() ||
        rtp_iterator != outgoing_rtp.end()) {
      return next_process_time_us_;
    }
    return std::numeric_limits<int64_t>::max();
  };

  RateStatistics raw_acked_bitrate(750, 8000);
  FieldTrials throughput_config(
      "WebRTC-Bwe-RobustThroughputEstimatorSettings/enabled:true/");
  std::unique_ptr<AcknowledgedBitrateEstimatorInterface>
      robust_throughput_estimator(
          AcknowledgedBitrateEstimatorInterface::Create(&throughput_config));
  FieldTrials acked_bitrate_config(
      "WebRTC-Bwe-RobustThroughputEstimatorSettings/enabled:false/");
  std::unique_ptr<AcknowledgedBitrateEstimatorInterface>
      acknowledged_bitrate_estimator(
          AcknowledgedBitrateEstimatorInterface::Create(&acked_bitrate_config));
  int64_t time_us =
      std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()});
  int64_t last_update_us = 0;
  while (time_us != std::numeric_limits<int64_t>::max()) {
    clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds());
    if (clock.TimeInMicroseconds() >= NextRtpTime()) {
      RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtpTime());
      const RtpPacketType& rtp_packet = *rtp_iterator->second;
      if (rtp_packet.rtp.header.extension.hasTransportSequenceNumber) {
        RtpPacketToSend send_packet(/*extensions=*/nullptr);
        send_packet.set_transport_sequence_number(
            rtp_packet.rtp.header.extension.transportSequenceNumber);
        send_packet.SetSsrc(rtp_packet.rtp.header.ssrc);
        send_packet.SetSequenceNumber(rtp_packet.rtp.header.sequenceNumber);
        send_packet.SetPayloadSize(rtp_packet.rtp.total_length -
                                   send_packet.headers_size());
        RTC_DCHECK_EQ(send_packet.size(), rtp_packet.rtp.total_length);
        if (IsRtxSsrc(parsed_log_, PacketDirection::kOutgoingPacket,
                      rtp_packet.rtp.header.ssrc)) {
          // Don't set the optional media type as we don't know if it is
          // a retransmission, FEC or padding.
        } else if (IsVideoSsrc(parsed_log_, PacketDirection::kOutgoingPacket,
                               rtp_packet.rtp.header.ssrc)) {
          send_packet.set_packet_type(RtpPacketMediaType::kVideo);
        } else if (IsAudioSsrc(parsed_log_, PacketDirection::kOutgoingPacket,
                               rtp_packet.rtp.header.ssrc)) {
          send_packet.set_packet_type(RtpPacketMediaType::kAudio);
        }
        transport_feedback.AddPacket(
            send_packet, PacedPacketInfo(),
            0u,  // Per packet overhead bytes.,
            Timestamp::Micros(rtp_packet.rtp.log_time_us()));
      }
      SentPacketInfo sent_packet;
      sent_packet.send_time_ms = rtp_packet.rtp.log_time_ms();
      sent_packet.info.included_in_allocation = true;
      sent_packet.info.packet_size_bytes = rtp_packet.rtp.total_length;
      if (rtp_packet.rtp.header.extension.hasTransportSequenceNumber) {
        sent_packet.packet_id =
            rtp_packet.rtp.header.extension.transportSequenceNumber;
        sent_packet.info.included_in_feedback = true;
      }
      auto sent_msg = transport_feedback.ProcessSentPacket(sent_packet);
      if (sent_msg)
        observer.Update(goog_cc->OnSentPacket(*sent_msg));
      ++rtp_iterator;
    }
    if (clock.TimeInMicroseconds() >= NextRtcpTime()) {
      RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime());

      auto feedback_msg = transport_feedback.ProcessTransportFeedback(
          rtcp_iterator->transport_feedback, clock.CurrentTime());
      if (feedback_msg) {
        observer.Update(goog_cc->OnTransportPacketsFeedback(*feedback_msg));
        std::vector<PacketResult> feedback =
            feedback_msg->SortedByReceiveTime();
        if (!feedback.empty()) {
          acknowledged_bitrate_estimator->IncomingPacketFeedbackVector(
              feedback);
          robust_throughput_estimator->IncomingPacketFeedbackVector(feedback);
          for (const PacketResult& packet : feedback) {
            raw_acked_bitrate.Update(packet.sent_packet.size.bytes(),
                                     packet.receive_time.ms());
          }
          std::optional<uint32_t> raw_bitrate_bps =
              raw_acked_bitrate.Rate(feedback.back().receive_time.ms());
          float x = config_.GetCallTimeSec(clock.CurrentTime());
          if (raw_bitrate_bps) {
            float y = raw_bitrate_bps.value() / 1000;
            acked_time_series.points.emplace_back(x, y);
          }
          std::optional<DataRate> robust_estimate =
              robust_throughput_estimator->bitrate();
          if (robust_estimate) {
            float y = robust_estimate.value().kbps();
            robust_time_series.points.emplace_back(x, y);
          }
          std::optional<DataRate> acked_estimate =
              acknowledged_bitrate_estimator->bitrate();
          if (acked_estimate) {
            float y = acked_estimate.value().kbps();
            acked_estimate_time_series.points.emplace_back(x, y);
          }
        }
      }
      ++rtcp_iterator;
    }
    if (clock.TimeInMicroseconds() >= NextProcessTime()) {
      RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextProcessTime());
      ProcessInterval msg;
      msg.at_time = clock.CurrentTime();
      observer.Update(goog_cc->OnProcessInterval(msg));
      next_process_time_us_ += process_interval.us();
    }
    if (observer.GetAndResetBitrateUpdated() ||
        time_us - last_update_us >= 1e6) {
      uint32_t y = observer.last_bitrate_bps() / 1000;
      float x = config_.GetCallTimeSec(clock.CurrentTime());
      time_series.points.emplace_back(x, y);
      last_update_us = time_us;
    }
    time_us = std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()});
  }
  // Add the data set to the plot.
  plot->AppendTimeSeries(std::move(time_series));
  plot->AppendTimeSeries(std::move(robust_time_series));
  plot->AppendTimeSeries(std::move(acked_time_series));
  plot->AppendTimeSeriesIfNotEmpty(std::move(acked_estimate_time_series));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin);
  plot->SetTitle("Simulated send-side BWE behavior");
}

void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) const {
  using RtpPacketType = LoggedRtpPacketIncoming;
  class RembInterceptor {
   public:
    void SendRemb(uint32_t bitrate_bps, std::vector<uint32_t> ssrcs) {
      last_bitrate_bps_ = bitrate_bps;
      bitrate_updated_ = true;
    }
    uint32_t last_bitrate_bps() const { return last_bitrate_bps_; }
    bool GetAndResetBitrateUpdated() {
      bool bitrate_updated = bitrate_updated_;
      bitrate_updated_ = false;
      return bitrate_updated;
    }

   private:
    // We don't know the start bitrate, but assume that it is the default 300
    // kbps.
    uint32_t last_bitrate_bps_ = 300000;
    bool bitrate_updated_ = false;
  };

  std::multimap<int64_t, const RtpPacketType*> incoming_rtp;

  for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) {
    if (IsVideoSsrc(parsed_log_, kIncomingPacket, stream.ssrc)) {
      for (const auto& rtp_packet : stream.incoming_packets)
        incoming_rtp.insert(
            std::make_pair(rtp_packet.rtp.log_time_us(), &rtp_packet));
    }
  }

  SimulatedClock clock(0);
  EnvironmentFactory env_factory(env_);
  env_factory.Set(&clock);
  RembInterceptor remb_interceptor;
  ReceiveSideCongestionController rscc(
      env_factory.Create(), [](auto...) {},
      absl::bind_front(&RembInterceptor::SendRemb, &remb_interceptor));
  // TODO(holmer): Log the call config and use that here instead.
  // static const uint32_t kDefaultStartBitrateBps = 300000;
  // rscc.SetBweBitrates(0, kDefaultStartBitrateBps, -1);

  TimeSeries time_series("Receive side estimate", LineStyle::kLine,
                         PointStyle::kHighlight);
  TimeSeries acked_time_series("Received bitrate", LineStyle::kLine);

  RateStatistics acked_bitrate(250, 8000);
  int64_t last_update_us = 0;
  for (const auto& kv : incoming_rtp) {
    const RtpPacketType& packet = *kv.second;

    RtpPacketReceived rtp_packet = RtpPacketForBWEFromHeader(packet.rtp.header);
    rtp_packet.set_arrival_time(packet.rtp.log_time());
    rtp_packet.SetPayloadSize(packet.rtp.total_length -
                              rtp_packet.headers_size());

    clock.AdvanceTime(rtp_packet.arrival_time() - clock.CurrentTime());
    rscc.OnReceivedPacket(rtp_packet, MediaType::VIDEO);
    int64_t arrival_time_ms = packet.rtp.log_time().ms();
    acked_bitrate.Update(packet.rtp.total_length, arrival_time_ms);
    std::optional<uint32_t> bitrate_bps = acked_bitrate.Rate(arrival_time_ms);
    if (bitrate_bps) {
      uint32_t y = *bitrate_bps / 1000;
      float x = config_.GetCallTimeSec(clock.CurrentTime());
      acked_time_series.points.emplace_back(x, y);
    }
    if (remb_interceptor.GetAndResetBitrateUpdated() ||
        clock.TimeInMicroseconds() - last_update_us >= 1e6) {
      uint32_t y = remb_interceptor.last_bitrate_bps() / 1000;
      float x = config_.GetCallTimeSec(clock.CurrentTime());
      time_series.points.emplace_back(x, y);
      last_update_us = clock.TimeInMicroseconds();
    }
  }
  // Add the data set to the plot.
  plot->AppendTimeSeries(std::move(time_series));
  plot->AppendTimeSeries(std::move(acked_time_series));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 10, "Bitrate (kbps)", kBottomMargin, kTopMargin);
  plot->SetTitle("Simulated receive-side BWE behavior");
}

void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) const {
  TimeSeries time_series("Network delay", LineStyle::kLine,
                         PointStyle::kHighlight);
  int64_t min_send_receive_diff_ms = std::numeric_limits<int64_t>::max();
  int64_t min_rtt_ms = std::numeric_limits<int64_t>::max();

  std::vector<MatchedSendArrivalTimes> matched_rtp_rtcp =
      GetNetworkTrace(parsed_log_);
  absl::c_stable_sort(matched_rtp_rtcp, [](const MatchedSendArrivalTimes& a,
                                           const MatchedSendArrivalTimes& b) {
    return a.feedback_arrival_time_ms < b.feedback_arrival_time_ms ||
           (a.feedback_arrival_time_ms == b.feedback_arrival_time_ms &&
            a.arrival_time_ms < b.arrival_time_ms);
  });
  for (const auto& packet : matched_rtp_rtcp) {
    if (packet.arrival_time_ms == MatchedSendArrivalTimes::kNotReceived)
      continue;
    float x = config_.GetCallTimeSecFromMs(packet.feedback_arrival_time_ms);
    int64_t y = packet.arrival_time_ms - packet.send_time_ms;
    int64_t rtt_ms = packet.feedback_arrival_time_ms - packet.send_time_ms;
    min_rtt_ms = std::min(rtt_ms, min_rtt_ms);
    min_send_receive_diff_ms = std::min(y, min_send_receive_diff_ms);
    time_series.points.emplace_back(x, y);
  }

  // We assume that the base network delay (w/o queues) is equal to half
  // the minimum RTT. Therefore rescale the delays by subtracting the minimum
  // observed 1-ways delay and add half the minimum RTT.
  const int64_t estimated_clock_offset_ms =
      min_send_receive_diff_ms - min_rtt_ms / 2;
  for (TimeSeriesPoint& point : time_series.points)
    point.y -= estimated_clock_offset_ms;

  // Add the data set to the plot.
  plot->AppendTimeSeriesIfNotEmpty(std::move(time_series));

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 10, "Delay (ms)", kBottomMargin, kTopMargin);
  plot->SetTitle("Outgoing network delay (based on per-packet feedback)");
}

void EventLogAnalyzer::CreatePacerDelayGraph(Plot* plot) const {
  for (const auto& stream : parsed_log_.outgoing_rtp_packets_by_ssrc()) {
    const std::vector<LoggedRtpPacketOutgoing>& packets =
        stream.outgoing_packets;

    if (IsRtxSsrc(parsed_log_, kOutgoingPacket, stream.ssrc)) {
      continue;
    }

    if (packets.size() < 2) {
      RTC_LOG(LS_WARNING)
          << "Can't estimate a the RTP clock frequency or the "
             "pacer delay with less than 2 packets in the stream";
      continue;
    }
    int64_t segment_end_us = parsed_log_.first_log_segment().stop_time_us();
    std::optional<uint32_t> estimated_frequency =
        EstimateRtpClockFrequency(packets, segment_end_us);
    if (!estimated_frequency)
      continue;
    if (IsVideoSsrc(parsed_log_, kOutgoingPacket, stream.ssrc) &&
        *estimated_frequency != 90000) {
      RTC_LOG(LS_WARNING)
          << "Video stream should use a 90 kHz clock but appears to use "
          << *estimated_frequency / 1000 << ". Discarding.";
      continue;
    }

    TimeSeries pacer_delay_series(
        GetStreamName(parsed_log_, kOutgoingPacket, stream.ssrc) + "(" +
            std::to_string(*estimated_frequency / 1000) + " kHz)",
        LineStyle::kLine, PointStyle::kHighlight);
    SeqNumUnwrapper<uint32_t> timestamp_unwrapper;
    uint64_t first_capture_timestamp =
        timestamp_unwrapper.Unwrap(packets.front().rtp.header.timestamp);
    uint64_t first_send_timestamp = packets.front().rtp.log_time_us();
    for (const auto& packet : packets) {
      double capture_time_ms = (static_cast<double>(timestamp_unwrapper.Unwrap(
                                    packet.rtp.header.timestamp)) -
                                first_capture_timestamp) /
                               *estimated_frequency * 1000;
      double send_time_ms =
          static_cast<double>(packet.rtp.log_time_us() - first_send_timestamp) /
          1000;
      float x = config_.GetCallTimeSec(packet.rtp.log_time());
      float y = send_time_ms - capture_time_ms;
      pacer_delay_series.points.emplace_back(x, y);
    }
    plot->AppendTimeSeries(std::move(pacer_delay_series));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 10, "Pacer delay (ms)", kBottomMargin, kTopMargin);
  plot->SetTitle(
      "Delay from capture to send time. (First packet normalized to 0.)");
}

void EventLogAnalyzer::CreateTimestampGraph(PacketDirection direction,
                                            Plot* plot) const {
  for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) {
    TimeSeries rtp_timestamps(
        GetStreamName(parsed_log_, direction, stream.ssrc) + " capture-time",
        LineStyle::kLine, PointStyle::kHighlight);
    for (const auto& packet : stream.packet_view) {
      float x = config_.GetCallTimeSec(packet.log_time());
      float y = packet.header.timestamp;
      rtp_timestamps.points.emplace_back(x, y);
    }
    plot->AppendTimeSeries(std::move(rtp_timestamps));

    TimeSeries rtcp_timestamps(
        GetStreamName(parsed_log_, direction, stream.ssrc) +
            " rtcp capture-time",
        LineStyle::kLine, PointStyle::kHighlight);
    // TODO(terelius): Why only sender reports?
    const auto& sender_reports = parsed_log_.sender_reports(direction);
    for (const auto& rtcp : sender_reports) {
      if (rtcp.sr.sender_ssrc() != stream.ssrc)
        continue;
      float x = config_.GetCallTimeSec(rtcp.log_time());
      float y = rtcp.sr.rtp_timestamp();
      rtcp_timestamps.points.emplace_back(x, y);
    }
    plot->AppendTimeSeriesIfNotEmpty(std::move(rtcp_timestamps));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "RTP timestamp", kBottomMargin, kTopMargin);
  plot->SetTitle(GetDirectionAsString(direction) + " timestamps");
}

void EventLogAnalyzer::CreateSenderAndReceiverReportPlot(
    PacketDirection direction,
    FunctionView<float(const rtcp::ReportBlock&)> fy,
    std::string title,
    std::string yaxis_label,
    Plot* plot) const {
  std::map<uint32_t, TimeSeries> sr_reports_by_ssrc;
  const auto& sender_reports = parsed_log_.sender_reports(direction);
  for (const auto& rtcp : sender_reports) {
    float x = config_.GetCallTimeSec(rtcp.log_time());
    uint32_t ssrc = rtcp.sr.sender_ssrc();
    for (const auto& block : rtcp.sr.report_blocks()) {
      float y = fy(block);
      auto sr_report_it = sr_reports_by_ssrc.find(ssrc);
      bool inserted;
      if (sr_report_it == sr_reports_by_ssrc.end()) {
        std::tie(sr_report_it, inserted) = sr_reports_by_ssrc.emplace(
            ssrc, TimeSeries(GetStreamName(parsed_log_, direction, ssrc) +
                                 " Sender Reports",
                             LineStyle::kLine, PointStyle::kHighlight));
      }
      sr_report_it->second.points.emplace_back(x, y);
    }
  }
  for (auto& kv : sr_reports_by_ssrc) {
    plot->AppendTimeSeries(std::move(kv.second));
  }

  std::map<uint32_t, TimeSeries> rr_reports_by_ssrc;
  const auto& receiver_reports = parsed_log_.receiver_reports(direction);
  for (const auto& rtcp : receiver_reports) {
    float x = config_.GetCallTimeSec(rtcp.log_time());
    uint32_t ssrc = rtcp.rr.sender_ssrc();
    for (const auto& block : rtcp.rr.report_blocks()) {
      float y = fy(block);
      auto rr_report_it = rr_reports_by_ssrc.find(ssrc);
      bool inserted;
      if (rr_report_it == rr_reports_by_ssrc.end()) {
        std::tie(rr_report_it, inserted) = rr_reports_by_ssrc.emplace(
            ssrc, TimeSeries(GetStreamName(parsed_log_, direction, ssrc) +
                                 " Receiver Reports",
                             LineStyle::kLine, PointStyle::kHighlight));
      }
      rr_report_it->second.points.emplace_back(x, y);
    }
  }
  for (auto& kv : rr_reports_by_ssrc) {
    plot->AppendTimeSeries(std::move(kv.second));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, yaxis_label, kBottomMargin, kTopMargin);
  plot->SetTitle(title);
}

void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) const {
  std::map<uint32_t, TimeSeries> configs_by_cp_id;
  for (const auto& config : parsed_log_.ice_candidate_pair_configs()) {
    if (configs_by_cp_id.find(config.candidate_pair_id) ==
        configs_by_cp_id.end()) {
      const std::string candidate_pair_desc =
          GetCandidatePairLogDescriptionAsString(config);
      configs_by_cp_id[config.candidate_pair_id] =
          TimeSeries("[" + std::to_string(config.candidate_pair_id) + "]" +
                         candidate_pair_desc,
                     LineStyle::kNone, PointStyle::kHighlight);
    }
    float x = config_.GetCallTimeSec(config.log_time());
    float y = static_cast<float>(config.type);
    configs_by_cp_id[config.candidate_pair_id].points.emplace_back(x, y);
  }

  // TODO(qingsi): There can be a large number of candidate pairs generated by
  // certain calls and the frontend cannot render the chart in this case due
  // to the failure of generating a palette with the same number of colors.
  for (auto& kv : configs_by_cp_id) {
    plot->AppendTimeSeries(std::move(kv.second));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 3, "Config Type", kBottomMargin, kTopMargin);
  plot->SetTitle("[IceEventLog] ICE candidate pair configs");
  plot->SetYAxisTickLabels(
      {{static_cast<float>(IceCandidatePairConfigType::kAdded), "ADDED"},
       {static_cast<float>(IceCandidatePairConfigType::kUpdated), "UPDATED"},
       {static_cast<float>(IceCandidatePairConfigType::kDestroyed),
        "DESTROYED"},
       {static_cast<float>(IceCandidatePairConfigType::kSelected),
        "SELECTED"}});
}

void EventLogAnalyzer::CreateIceConnectivityCheckGraph(Plot* plot) const {
  constexpr int kEventTypeOffset =
      static_cast<int>(IceCandidatePairConfigType::kNumValues);
  std::map<uint32_t, TimeSeries> checks_by_cp_id;
  std::map<uint32_t, std::string> candidate_pair_desc_by_id =
      BuildCandidateIdLogDescriptionMap(
          parsed_log_.ice_candidate_pair_configs());
  for (const auto& event : parsed_log_.ice_candidate_pair_events()) {
    if (checks_by_cp_id.find(event.candidate_pair_id) ==
        checks_by_cp_id.end()) {
      checks_by_cp_id[event.candidate_pair_id] =
          TimeSeries("[" + std::to_string(event.candidate_pair_id) + "]" +
                         candidate_pair_desc_by_id[event.candidate_pair_id],
                     LineStyle::kNone, PointStyle::kHighlight);
    }
    float x = config_.GetCallTimeSec(event.log_time());
    float y = static_cast<float>(event.type) + kEventTypeOffset;
    checks_by_cp_id[event.candidate_pair_id].points.emplace_back(x, y);
  }

  // TODO(qingsi): The same issue as in CreateIceCandidatePairConfigGraph.
  for (auto& kv : checks_by_cp_id) {
    plot->AppendTimeSeries(std::move(kv.second));
  }

  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 4, "Connectivity State", kBottomMargin,
                          kTopMargin);
  plot->SetTitle("[IceEventLog] ICE connectivity checks");

  plot->SetYAxisTickLabels(
      {{static_cast<float>(IceCandidatePairEventType::kCheckSent) +
            kEventTypeOffset,
        "CHECK SENT"},
       {static_cast<float>(IceCandidatePairEventType::kCheckReceived) +
            kEventTypeOffset,
        "CHECK RECEIVED"},
       {static_cast<float>(IceCandidatePairEventType::kCheckResponseSent) +
            kEventTypeOffset,
        "RESPONSE SENT"},
       {static_cast<float>(IceCandidatePairEventType::kCheckResponseReceived) +
            kEventTypeOffset,
        "RESPONSE RECEIVED"}});
}

void EventLogAnalyzer::CreateDtlsTransportStateGraph(Plot* plot) const {
  TimeSeries states("DTLS Transport State", LineStyle::kNone,
                    PointStyle::kHighlight);
  for (const auto& event : parsed_log_.dtls_transport_states()) {
    float x = config_.GetCallTimeSec(event.log_time());
    float y = static_cast<float>(event.dtls_transport_state);
    states.points.emplace_back(x, y);
  }
  plot->AppendTimeSeries(std::move(states));
  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, static_cast<float>(DtlsTransportState::kNumValues),
                          "Transport State", kBottomMargin, kTopMargin);
  plot->SetTitle("DTLS Transport State");
  plot->SetYAxisTickLabels(
      {{static_cast<float>(DtlsTransportState::kNew), "NEW"},
       {static_cast<float>(DtlsTransportState::kConnecting), "CONNECTING"},
       {static_cast<float>(DtlsTransportState::kConnected), "CONNECTED"},
       {static_cast<float>(DtlsTransportState::kClosed), "CLOSED"},
       {static_cast<float>(DtlsTransportState::kFailed), "FAILED"}});
}

void EventLogAnalyzer::CreateDtlsWritableStateGraph(Plot* plot) const {
  TimeSeries writable("DTLS Writable", LineStyle::kNone,
                      PointStyle::kHighlight);
  for (const auto& event : parsed_log_.dtls_writable_states()) {
    float x = config_.GetCallTimeSec(event.log_time());
    float y = static_cast<float>(event.writable);
    writable.points.emplace_back(x, y);
  }
  plot->AppendTimeSeries(std::move(writable));
  plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
                 "Time (s)", kLeftMargin, kRightMargin);
  plot->SetSuggestedYAxis(0, 1, "Writable", kBottomMargin, kTopMargin);
  plot->SetTitle("DTLS Writable State");
}

}  // namespace webrtc
