/*
 *  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 "logging/rtc_event_log/rtc_event_log_parser.h"

#include <stdint.h>
#include <string.h>

#include <algorithm>
#include <limits>
#include <map>
#include <utility>

#include "absl/memory/memory.h"
#include "absl/types/optional.h"
#include "api/network_state_predictor.h"
#include "api/rtc_event_log/rtc_event_log.h"
#include "api/rtp_headers.h"
#include "api/rtp_parameters.h"
#include "logging/rtc_event_log/encoder/blob_encoding.h"
#include "logging/rtc_event_log/encoder/delta_encoding.h"
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
#include "logging/rtc_event_log/encoder/var_int.h"
#include "logging/rtc_event_log/rtc_event_processor.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
#include "modules/include/module_common_types_public.h"
#include "modules/rtp_rtcp/include/rtp_cvo.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_utility.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/numerics/sequence_number_util.h"
#include "rtc_base/protobuf_utils.h"
#include "rtc_base/system/file_wrapper.h"

// These macros were added to convert existing code using RTC_CHECKs
// to returning a Status object instead. Macros are necessary (over
// e.g. helper functions) since we want to return from the current
// function.
#define RTC_PARSE_CHECK_OR_RETURN(X)                                        \
  do {                                                                      \
    if (!(X))                                                               \
      return ParsedRtcEventLog::ParseStatus::Error(#X, __FILE__, __LINE__); \
  } while (0)

#define RTC_PARSE_CHECK_OR_RETURN_OP(OP, X, Y)                          \
  do {                                                                  \
    if (!((X)OP(Y)))                                                    \
      return ParsedRtcEventLog::ParseStatus::Error(#X #OP #Y, __FILE__, \
                                                   __LINE__);           \
  } while (0)

#define RTC_PARSE_CHECK_OR_RETURN_EQ(X, Y) \
  RTC_PARSE_CHECK_OR_RETURN_OP(==, X, Y)

#define RTC_PARSE_CHECK_OR_RETURN_NE(X, Y) \
  RTC_PARSE_CHECK_OR_RETURN_OP(!=, X, Y)

#define RTC_PARSE_CHECK_OR_RETURN_LT(X, Y) RTC_PARSE_CHECK_OR_RETURN_OP(<, X, Y)

#define RTC_PARSE_CHECK_OR_RETURN_LE(X, Y) \
  RTC_PARSE_CHECK_OR_RETURN_OP(<=, X, Y)

#define RTC_PARSE_CHECK_OR_RETURN_GT(X, Y) RTC_PARSE_CHECK_OR_RETURN_OP(>, X, Y)

#define RTC_PARSE_CHECK_OR_RETURN_GE(X, Y) \
  RTC_PARSE_CHECK_OR_RETURN_OP(>=, X, Y)

#define RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(X, M)      \
  do {                                                  \
    if (X) {                                            \
      RTC_LOG(LS_WARNING) << (M);                       \
      return ParsedRtcEventLog::ParseStatus::Success(); \
    }                                                   \
  } while (0)

#define RTC_RETURN_IF_ERROR(X)                                 \
  do {                                                         \
    const ParsedRtcEventLog::ParseStatus _rtc_parse_status(X); \
    if (!_rtc_parse_status.ok()) {                             \
      return _rtc_parse_status;                                \
    }                                                          \
  } while (0)

using webrtc_event_logging::ToSigned;
using webrtc_event_logging::ToUnsigned;

namespace webrtc {

namespace {
constexpr int64_t kMaxLogSize = 250000000;

constexpr size_t kIpv4Overhead = 20;
constexpr size_t kIpv6Overhead = 40;
constexpr size_t kUdpOverhead = 8;
constexpr size_t kSrtpOverhead = 10;
constexpr size_t kStunOverhead = 4;
constexpr uint16_t kDefaultOverhead =
    kUdpOverhead + kSrtpOverhead + kIpv4Overhead;

constexpr char kIncompleteLogError[] =
    "Could not parse the entire log. Only the beginning will be used.";

struct MediaStreamInfo {
  MediaStreamInfo() = default;
  MediaStreamInfo(LoggedMediaType media_type, bool rtx)
      : media_type(media_type), rtx(rtx) {}
  LoggedMediaType media_type = LoggedMediaType::kUnknown;
  bool rtx = false;
  SeqNumUnwrapper<uint32_t> unwrap_capture_ticks;
};

template <typename Iterable>
void AddRecvStreamInfos(std::map<uint32_t, MediaStreamInfo>* streams,
                        const Iterable configs,
                        LoggedMediaType media_type) {
  for (auto& conf : configs) {
    streams->insert({conf.config.remote_ssrc, {media_type, false}});
    if (conf.config.rtx_ssrc != 0)
      streams->insert({conf.config.rtx_ssrc, {media_type, true}});
  }
}
template <typename Iterable>
void AddSendStreamInfos(std::map<uint32_t, MediaStreamInfo>* streams,
                        const Iterable configs,
                        LoggedMediaType media_type) {
  for (auto& conf : configs) {
    streams->insert({conf.config.local_ssrc, {media_type, false}});
    if (conf.config.rtx_ssrc != 0)
      streams->insert({conf.config.rtx_ssrc, {media_type, true}});
  }
}
struct OverheadChangeEvent {
  Timestamp timestamp;
  uint16_t overhead;
};
std::vector<OverheadChangeEvent> GetOverheadChangingEvents(
    const std::vector<InferredRouteChangeEvent>& route_changes,
    PacketDirection direction) {
  std::vector<OverheadChangeEvent> overheads;
  for (auto& event : route_changes) {
    uint16_t new_overhead = direction == PacketDirection::kIncomingPacket
                                ? event.return_overhead
                                : event.send_overhead;
    if (overheads.empty() || new_overhead != overheads.back().overhead) {
      overheads.push_back({event.log_time, new_overhead});
    }
  }
  return overheads;
}

bool IdenticalRtcpContents(const std::vector<uint8_t>& last_rtcp,
                           absl::string_view new_rtcp) {
  if (last_rtcp.size() != new_rtcp.size())
    return false;
  return memcmp(last_rtcp.data(), new_rtcp.data(), new_rtcp.size()) == 0;
}

// Conversion functions for legacy wire format.
RtcpMode GetRuntimeRtcpMode(rtclog::VideoReceiveConfig::RtcpMode rtcp_mode) {
  switch (rtcp_mode) {
    case rtclog::VideoReceiveConfig::RTCP_COMPOUND:
      return RtcpMode::kCompound;
    case rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE:
      return RtcpMode::kReducedSize;
  }
  RTC_NOTREACHED();
  return RtcpMode::kOff;
}

BandwidthUsage GetRuntimeDetectorState(
    rtclog::DelayBasedBweUpdate::DetectorState detector_state) {
  switch (detector_state) {
    case rtclog::DelayBasedBweUpdate::BWE_NORMAL:
      return BandwidthUsage::kBwNormal;
    case rtclog::DelayBasedBweUpdate::BWE_UNDERUSING:
      return BandwidthUsage::kBwUnderusing;
    case rtclog::DelayBasedBweUpdate::BWE_OVERUSING:
      return BandwidthUsage::kBwOverusing;
  }
  RTC_NOTREACHED();
  return BandwidthUsage::kBwNormal;
}

IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType(
    rtclog::IceCandidatePairConfig::IceCandidatePairConfigType type) {
  switch (type) {
    case rtclog::IceCandidatePairConfig::ADDED:
      return IceCandidatePairConfigType::kAdded;
    case rtclog::IceCandidatePairConfig::UPDATED:
      return IceCandidatePairConfigType::kUpdated;
    case rtclog::IceCandidatePairConfig::DESTROYED:
      return IceCandidatePairConfigType::kDestroyed;
    case rtclog::IceCandidatePairConfig::SELECTED:
      return IceCandidatePairConfigType::kSelected;
  }
  RTC_NOTREACHED();
  return IceCandidatePairConfigType::kAdded;
}

IceCandidateType GetRuntimeIceCandidateType(
    rtclog::IceCandidatePairConfig::IceCandidateType type) {
  switch (type) {
    case rtclog::IceCandidatePairConfig::LOCAL:
      return IceCandidateType::kLocal;
    case rtclog::IceCandidatePairConfig::STUN:
      return IceCandidateType::kStun;
    case rtclog::IceCandidatePairConfig::PRFLX:
      return IceCandidateType::kPrflx;
    case rtclog::IceCandidatePairConfig::RELAY:
      return IceCandidateType::kRelay;
    case rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE:
      return IceCandidateType::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidateType::kUnknown;
}

IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
    rtclog::IceCandidatePairConfig::Protocol protocol) {
  switch (protocol) {
    case rtclog::IceCandidatePairConfig::UDP:
      return IceCandidatePairProtocol::kUdp;
    case rtclog::IceCandidatePairConfig::TCP:
      return IceCandidatePairProtocol::kTcp;
    case rtclog::IceCandidatePairConfig::SSLTCP:
      return IceCandidatePairProtocol::kSsltcp;
    case rtclog::IceCandidatePairConfig::TLS:
      return IceCandidatePairProtocol::kTls;
    case rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL:
      return IceCandidatePairProtocol::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidatePairProtocol::kUnknown;
}

IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
    rtclog::IceCandidatePairConfig::AddressFamily address_family) {
  switch (address_family) {
    case rtclog::IceCandidatePairConfig::IPV4:
      return IceCandidatePairAddressFamily::kIpv4;
    case rtclog::IceCandidatePairConfig::IPV6:
      return IceCandidatePairAddressFamily::kIpv6;
    case rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY:
      return IceCandidatePairAddressFamily::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidatePairAddressFamily::kUnknown;
}

IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
    rtclog::IceCandidatePairConfig::NetworkType network_type) {
  switch (network_type) {
    case rtclog::IceCandidatePairConfig::ETHERNET:
      return IceCandidateNetworkType::kEthernet;
    case rtclog::IceCandidatePairConfig::LOOPBACK:
      return IceCandidateNetworkType::kLoopback;
    case rtclog::IceCandidatePairConfig::WIFI:
      return IceCandidateNetworkType::kWifi;
    case rtclog::IceCandidatePairConfig::VPN:
      return IceCandidateNetworkType::kVpn;
    case rtclog::IceCandidatePairConfig::CELLULAR:
      return IceCandidateNetworkType::kCellular;
    case rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE:
      return IceCandidateNetworkType::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidateNetworkType::kUnknown;
}

IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
    rtclog::IceCandidatePairEvent::IceCandidatePairEventType type) {
  switch (type) {
    case rtclog::IceCandidatePairEvent::CHECK_SENT:
      return IceCandidatePairEventType::kCheckSent;
    case rtclog::IceCandidatePairEvent::CHECK_RECEIVED:
      return IceCandidatePairEventType::kCheckReceived;
    case rtclog::IceCandidatePairEvent::CHECK_RESPONSE_SENT:
      return IceCandidatePairEventType::kCheckResponseSent;
    case rtclog::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED:
      return IceCandidatePairEventType::kCheckResponseReceived;
  }
  RTC_NOTREACHED();
  return IceCandidatePairEventType::kCheckSent;
}

VideoCodecType GetRuntimeCodecType(rtclog2::FrameDecodedEvents::Codec codec) {
  switch (codec) {
    case rtclog2::FrameDecodedEvents::CODEC_GENERIC:
      return VideoCodecType::kVideoCodecGeneric;
    case rtclog2::FrameDecodedEvents::CODEC_VP8:
      return VideoCodecType::kVideoCodecVP8;
    case rtclog2::FrameDecodedEvents::CODEC_VP9:
      return VideoCodecType::kVideoCodecVP9;
    case rtclog2::FrameDecodedEvents::CODEC_AV1:
      return VideoCodecType::kVideoCodecAV1;
    case rtclog2::FrameDecodedEvents::CODEC_H264:
      return VideoCodecType::kVideoCodecH264;
    case rtclog2::FrameDecodedEvents::CODEC_UNKNOWN:
      RTC_LOG(LS_ERROR) << "Unknown codec type. Assuming "
                           "VideoCodecType::kVideoCodecMultiplex";
      return VideoCodecType::kVideoCodecMultiplex;
  }
  RTC_NOTREACHED();
  return VideoCodecType::kVideoCodecMultiplex;
}

ParsedRtcEventLog::ParseStatus GetHeaderExtensions(
    std::vector<RtpExtension>* header_extensions,
    const RepeatedPtrField<rtclog::RtpHeaderExtension>&
        proto_header_extensions) {
  header_extensions->clear();
  for (auto& p : proto_header_extensions) {
    RTC_PARSE_CHECK_OR_RETURN(p.has_name());
    RTC_PARSE_CHECK_OR_RETURN(p.has_id());
    const std::string& name = p.name();
    int id = p.id();
    header_extensions->push_back(RtpExtension(name, id));
  }
  return ParsedRtcEventLog::ParseStatus::Success();
}

template <typename ProtoType, typename LoggedType>
ParsedRtcEventLog::ParseStatus StoreRtpPackets(
    const ProtoType& proto,
    std::map<uint32_t, std::vector<LoggedType>>* rtp_packets_map) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_marker());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_payload_type());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_sequence_number());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_rtp_timestamp());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_payload_size());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_header_size());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_padding_size());

  // Base event
  {
    RTPHeader header;
    header.markerBit = rtc::checked_cast<bool>(proto.marker());
    header.payloadType = rtc::checked_cast<uint8_t>(proto.payload_type());
    header.sequenceNumber =
        rtc::checked_cast<uint16_t>(proto.sequence_number());
    header.timestamp = rtc::checked_cast<uint32_t>(proto.rtp_timestamp());
    header.ssrc = rtc::checked_cast<uint32_t>(proto.ssrc());
    header.numCSRCs = 0;  // TODO(terelius): Implement CSRC.
    header.paddingLength = rtc::checked_cast<size_t>(proto.padding_size());
    header.headerLength = rtc::checked_cast<size_t>(proto.header_size());
    // TODO(terelius): Should we implement payload_type_frequency?
    if (proto.has_transport_sequence_number()) {
      header.extension.hasTransportSequenceNumber = true;
      header.extension.transportSequenceNumber =
          rtc::checked_cast<uint16_t>(proto.transport_sequence_number());
    }
    if (proto.has_transmission_time_offset()) {
      header.extension.hasTransmissionTimeOffset = true;
      header.extension.transmissionTimeOffset =
          rtc::checked_cast<int32_t>(proto.transmission_time_offset());
    }
    if (proto.has_absolute_send_time()) {
      header.extension.hasAbsoluteSendTime = true;
      header.extension.absoluteSendTime =
          rtc::checked_cast<uint32_t>(proto.absolute_send_time());
    }
    if (proto.has_video_rotation()) {
      header.extension.hasVideoRotation = true;
      header.extension.videoRotation = ConvertCVOByteToVideoRotation(
          rtc::checked_cast<uint8_t>(proto.video_rotation()));
    }
    if (proto.has_audio_level()) {
      RTC_PARSE_CHECK_OR_RETURN(proto.has_voice_activity());
      header.extension.hasAudioLevel = true;
      header.extension.voiceActivity =
          rtc::checked_cast<bool>(proto.voice_activity());
      const uint8_t audio_level =
          rtc::checked_cast<uint8_t>(proto.audio_level());
      RTC_PARSE_CHECK_OR_RETURN_LE(audio_level, 0x7Fu);
      header.extension.audioLevel = audio_level;
    } else {
      RTC_PARSE_CHECK_OR_RETURN(!proto.has_voice_activity());
    }
    (*rtp_packets_map)[header.ssrc].emplace_back(
        Timestamp::Millis(proto.timestamp_ms()), header, proto.header_size(),
        proto.payload_size() + header.headerLength + header.paddingLength);
  }

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParsedRtcEventLog::ParseStatus::Success();
  }

  // timestamp_ms (event)
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // marker (RTP base)
  std::vector<absl::optional<uint64_t>> marker_values =
      DecodeDeltas(proto.marker_deltas(), proto.marker(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(marker_values.size(), number_of_deltas);

  // payload_type (RTP base)
  std::vector<absl::optional<uint64_t>> payload_type_values = DecodeDeltas(
      proto.payload_type_deltas(), proto.payload_type(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(payload_type_values.size(), number_of_deltas);

  // sequence_number (RTP base)
  std::vector<absl::optional<uint64_t>> sequence_number_values =
      DecodeDeltas(proto.sequence_number_deltas(), proto.sequence_number(),
                   number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(sequence_number_values.size(), number_of_deltas);

  // rtp_timestamp (RTP base)
  std::vector<absl::optional<uint64_t>> rtp_timestamp_values = DecodeDeltas(
      proto.rtp_timestamp_deltas(), proto.rtp_timestamp(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(rtp_timestamp_values.size(), number_of_deltas);

  // ssrc (RTP base)
  std::vector<absl::optional<uint64_t>> ssrc_values =
      DecodeDeltas(proto.ssrc_deltas(), proto.ssrc(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(ssrc_values.size(), number_of_deltas);

  // payload_size (RTP base)
  std::vector<absl::optional<uint64_t>> payload_size_values = DecodeDeltas(
      proto.payload_size_deltas(), proto.payload_size(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(payload_size_values.size(), number_of_deltas);

  // header_size (RTP base)
  std::vector<absl::optional<uint64_t>> header_size_values = DecodeDeltas(
      proto.header_size_deltas(), proto.header_size(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(header_size_values.size(), number_of_deltas);

  // padding_size (RTP base)
  std::vector<absl::optional<uint64_t>> padding_size_values = DecodeDeltas(
      proto.padding_size_deltas(), proto.padding_size(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(padding_size_values.size(), number_of_deltas);

  // transport_sequence_number (RTP extension)
  std::vector<absl::optional<uint64_t>> transport_sequence_number_values;
  {
    const absl::optional<uint64_t> base_transport_sequence_number =
        proto.has_transport_sequence_number()
            ? proto.transport_sequence_number()
            : absl::optional<uint64_t>();
    transport_sequence_number_values =
        DecodeDeltas(proto.transport_sequence_number_deltas(),
                     base_transport_sequence_number, number_of_deltas);
    RTC_PARSE_CHECK_OR_RETURN_EQ(transport_sequence_number_values.size(),
                                 number_of_deltas);
  }

  // transmission_time_offset (RTP extension)
  std::vector<absl::optional<uint64_t>> transmission_time_offset_values;
  {
    const absl::optional<uint64_t> unsigned_base_transmission_time_offset =
        proto.has_transmission_time_offset()
            ? ToUnsigned(proto.transmission_time_offset())
            : absl::optional<uint64_t>();
    transmission_time_offset_values =
        DecodeDeltas(proto.transmission_time_offset_deltas(),
                     unsigned_base_transmission_time_offset, number_of_deltas);
    RTC_PARSE_CHECK_OR_RETURN_EQ(transmission_time_offset_values.size(),
                                 number_of_deltas);
  }

  // absolute_send_time (RTP extension)
  std::vector<absl::optional<uint64_t>> absolute_send_time_values;
  {
    const absl::optional<uint64_t> base_absolute_send_time =
        proto.has_absolute_send_time() ? proto.absolute_send_time()
                                       : absl::optional<uint64_t>();
    absolute_send_time_values =
        DecodeDeltas(proto.absolute_send_time_deltas(), base_absolute_send_time,
                     number_of_deltas);
    RTC_PARSE_CHECK_OR_RETURN_EQ(absolute_send_time_values.size(),
                                 number_of_deltas);
  }

  // video_rotation (RTP extension)
  std::vector<absl::optional<uint64_t>> video_rotation_values;
  {
    const absl::optional<uint64_t> base_video_rotation =
        proto.has_video_rotation() ? proto.video_rotation()
                                   : absl::optional<uint64_t>();
    video_rotation_values = DecodeDeltas(proto.video_rotation_deltas(),
                                         base_video_rotation, number_of_deltas);
    RTC_PARSE_CHECK_OR_RETURN_EQ(video_rotation_values.size(),
                                 number_of_deltas);
  }

  // audio_level (RTP extension)
  std::vector<absl::optional<uint64_t>> audio_level_values;
  {
    const absl::optional<uint64_t> base_audio_level =
        proto.has_audio_level() ? proto.audio_level()
                                : absl::optional<uint64_t>();
    audio_level_values = DecodeDeltas(proto.audio_level_deltas(),
                                      base_audio_level, number_of_deltas);
    RTC_PARSE_CHECK_OR_RETURN_EQ(audio_level_values.size(), number_of_deltas);
  }

  // voice_activity (RTP extension)
  std::vector<absl::optional<uint64_t>> voice_activity_values;
  {
    const absl::optional<uint64_t> base_voice_activity =
        proto.has_voice_activity() ? proto.voice_activity()
                                   : absl::optional<uint64_t>();
    voice_activity_values = DecodeDeltas(proto.voice_activity_deltas(),
                                         base_voice_activity, number_of_deltas);
    RTC_PARSE_CHECK_OR_RETURN_EQ(voice_activity_values.size(),
                                 number_of_deltas);
  }

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(marker_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(payload_type_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(sequence_number_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(rtp_timestamp_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(ssrc_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(payload_size_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(header_size_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(padding_size_values[i].has_value());

    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));

    RTPHeader header;
    header.markerBit = rtc::checked_cast<bool>(*marker_values[i]);
    header.payloadType = rtc::checked_cast<uint8_t>(*payload_type_values[i]);
    header.sequenceNumber =
        rtc::checked_cast<uint16_t>(*sequence_number_values[i]);
    header.timestamp = rtc::checked_cast<uint32_t>(*rtp_timestamp_values[i]);
    header.ssrc = rtc::checked_cast<uint32_t>(*ssrc_values[i]);
    header.numCSRCs = 0;  // TODO(terelius): Implement CSRC.
    header.paddingLength = rtc::checked_cast<size_t>(*padding_size_values[i]);
    header.headerLength = rtc::checked_cast<size_t>(*header_size_values[i]);
    // TODO(terelius): Should we implement payload_type_frequency?
    if (transport_sequence_number_values.size() > i &&
        transport_sequence_number_values[i].has_value()) {
      header.extension.hasTransportSequenceNumber = true;
      header.extension.transportSequenceNumber = rtc::checked_cast<uint16_t>(
          transport_sequence_number_values[i].value());
    }
    if (transmission_time_offset_values.size() > i &&
        transmission_time_offset_values[i].has_value()) {
      header.extension.hasTransmissionTimeOffset = true;
      int32_t transmission_time_offset;
      RTC_PARSE_CHECK_OR_RETURN(
          ToSigned(transmission_time_offset_values[i].value(),
                   &transmission_time_offset));
      header.extension.transmissionTimeOffset = transmission_time_offset;
    }
    if (absolute_send_time_values.size() > i &&
        absolute_send_time_values[i].has_value()) {
      header.extension.hasAbsoluteSendTime = true;
      header.extension.absoluteSendTime =
          rtc::checked_cast<uint32_t>(absolute_send_time_values[i].value());
    }
    if (video_rotation_values.size() > i &&
        video_rotation_values[i].has_value()) {
      header.extension.hasVideoRotation = true;
      header.extension.videoRotation = ConvertCVOByteToVideoRotation(
          rtc::checked_cast<uint8_t>(video_rotation_values[i].value()));
    }
    if (audio_level_values.size() > i && audio_level_values[i].has_value()) {
      RTC_PARSE_CHECK_OR_RETURN(voice_activity_values.size() > i &&
                                voice_activity_values[i].has_value());
      header.extension.hasAudioLevel = true;
      header.extension.voiceActivity =
          rtc::checked_cast<bool>(voice_activity_values[i].value());
      const uint8_t audio_level =
          rtc::checked_cast<uint8_t>(audio_level_values[i].value());
      RTC_PARSE_CHECK_OR_RETURN_LE(audio_level, 0x7Fu);
      header.extension.audioLevel = audio_level;
    } else {
      RTC_PARSE_CHECK_OR_RETURN(voice_activity_values.size() <= i ||
                                !voice_activity_values[i].has_value());
    }
    (*rtp_packets_map)[header.ssrc].emplace_back(
        Timestamp::Millis(timestamp_ms), header, header.headerLength,
        payload_size_values[i].value() + header.headerLength +
            header.paddingLength);
  }
  return ParsedRtcEventLog::ParseStatus::Success();
}

template <typename ProtoType, typename LoggedType>
ParsedRtcEventLog::ParseStatus StoreRtcpPackets(
    const ProtoType& proto,
    std::vector<LoggedType>* rtcp_packets,
    bool remove_duplicates) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_raw_packet());

  // TODO(terelius): Incoming RTCP may be delivered once for audio and once
  // for video. As a work around, we remove the duplicated packets since they
  // cause problems when analyzing the log or feeding it into the transport
  // feedback adapter.
  if (!remove_duplicates || rtcp_packets->empty() ||
      !IdenticalRtcpContents(rtcp_packets->back().rtcp.raw_data,
                             proto.raw_packet())) {
    // Base event
    rtcp_packets->emplace_back(Timestamp::Millis(proto.timestamp_ms()),
                               proto.raw_packet());
  }

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParsedRtcEventLog::ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // raw_packet
  RTC_PARSE_CHECK_OR_RETURN(proto.has_raw_packet_blobs());
  std::vector<absl::string_view> raw_packet_values =
      DecodeBlobs(proto.raw_packet_blobs(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(raw_packet_values.size(), number_of_deltas);

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));

    // TODO(terelius): Incoming RTCP may be delivered once for audio and once
    // for video. As a work around, we remove the duplicated packets since they
    // cause problems when analyzing the log or feeding it into the transport
    // feedback adapter.
    if (remove_duplicates && !rtcp_packets->empty() &&
        IdenticalRtcpContents(rtcp_packets->back().rtcp.raw_data,
                              raw_packet_values[i])) {
      continue;
    }
    std::string data(raw_packet_values[i]);
    rtcp_packets->emplace_back(Timestamp::Millis(timestamp_ms), data);
  }
  return ParsedRtcEventLog::ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus StoreRtcpBlocks(
    int64_t timestamp_us,
    const uint8_t* packet_begin,
    const uint8_t* packet_end,
    std::vector<LoggedRtcpPacketSenderReport>* sr_list,
    std::vector<LoggedRtcpPacketReceiverReport>* rr_list,
    std::vector<LoggedRtcpPacketExtendedReports>* xr_list,
    std::vector<LoggedRtcpPacketRemb>* remb_list,
    std::vector<LoggedRtcpPacketNack>* nack_list,
    std::vector<LoggedRtcpPacketFir>* fir_list,
    std::vector<LoggedRtcpPacketPli>* pli_list,
    std::vector<LoggedRtcpPacketBye>* bye_list,
    std::vector<LoggedRtcpPacketTransportFeedback>* transport_feedback_list,
    std::vector<LoggedRtcpPacketLossNotification>* loss_notification_list) {
  Timestamp timestamp = Timestamp::Micros(timestamp_us);
  rtcp::CommonHeader header;
  for (const uint8_t* block = packet_begin; block < packet_end;
       block = header.NextPacket()) {
    RTC_PARSE_CHECK_OR_RETURN(header.Parse(block, packet_end - block));
    if (header.type() == rtcp::TransportFeedback::kPacketType &&
        header.fmt() == rtcp::TransportFeedback::kFeedbackMessageType) {
      LoggedRtcpPacketTransportFeedback parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.transport_feedback.Parse(header))
        transport_feedback_list->push_back(std::move(parsed_block));
    } else if (header.type() == rtcp::SenderReport::kPacketType) {
      LoggedRtcpPacketSenderReport parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.sr.Parse(header)) {
        sr_list->push_back(std::move(parsed_block));
      }
    } else if (header.type() == rtcp::ReceiverReport::kPacketType) {
      LoggedRtcpPacketReceiverReport parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.rr.Parse(header)) {
        rr_list->push_back(std::move(parsed_block));
      }
    } else if (header.type() == rtcp::ExtendedReports::kPacketType) {
      LoggedRtcpPacketExtendedReports parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.xr.Parse(header)) {
        xr_list->push_back(std::move(parsed_block));
      }
    } else if (header.type() == rtcp::Fir::kPacketType &&
               header.fmt() == rtcp::Fir::kFeedbackMessageType) {
      LoggedRtcpPacketFir parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.fir.Parse(header)) {
        fir_list->push_back(std::move(parsed_block));
      }
    } else if (header.type() == rtcp::Pli::kPacketType &&
               header.fmt() == rtcp::Pli::kFeedbackMessageType) {
      LoggedRtcpPacketPli parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.pli.Parse(header)) {
        pli_list->push_back(std::move(parsed_block));
      }
    } else if (header.type() == rtcp::Bye::kPacketType) {
      LoggedRtcpPacketBye parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.bye.Parse(header)) {
        bye_list->push_back(std::move(parsed_block));
      }
    } else if (header.type() == rtcp::Psfb::kPacketType &&
               header.fmt() == rtcp::Psfb::kAfbMessageType) {
      bool type_found = false;
      if (!type_found) {
        LoggedRtcpPacketRemb parsed_block;
        parsed_block.timestamp = timestamp;
        if (parsed_block.remb.Parse(header)) {
          remb_list->push_back(std::move(parsed_block));
          type_found = true;
        }
      }
      if (!type_found) {
        LoggedRtcpPacketLossNotification parsed_block;
        parsed_block.timestamp = timestamp;
        if (parsed_block.loss_notification.Parse(header)) {
          loss_notification_list->push_back(std::move(parsed_block));
          type_found = true;
        }
      }
    } else if (header.type() == rtcp::Nack::kPacketType &&
               header.fmt() == rtcp::Nack::kFeedbackMessageType) {
      LoggedRtcpPacketNack parsed_block;
      parsed_block.timestamp = timestamp;
      if (parsed_block.nack.Parse(header)) {
        nack_list->push_back(std::move(parsed_block));
      }
    }
  }
  return ParsedRtcEventLog::ParseStatus::Success();
}

}  // namespace

// Conversion functions for version 2 of the wire format.
BandwidthUsage GetRuntimeDetectorState(
    rtclog2::DelayBasedBweUpdates::DetectorState detector_state) {
  switch (detector_state) {
    case rtclog2::DelayBasedBweUpdates::BWE_NORMAL:
      return BandwidthUsage::kBwNormal;
    case rtclog2::DelayBasedBweUpdates::BWE_UNDERUSING:
      return BandwidthUsage::kBwUnderusing;
    case rtclog2::DelayBasedBweUpdates::BWE_OVERUSING:
      return BandwidthUsage::kBwOverusing;
    case rtclog2::DelayBasedBweUpdates::BWE_UNKNOWN_STATE:
      break;
  }
  RTC_NOTREACHED();
  return BandwidthUsage::kBwNormal;
}

ProbeFailureReason GetRuntimeProbeFailureReason(
    rtclog2::BweProbeResultFailure::FailureReason failure) {
  switch (failure) {
    case rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_INTERVAL:
      return ProbeFailureReason::kInvalidSendReceiveInterval;
    case rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_RATIO:
      return ProbeFailureReason::kInvalidSendReceiveRatio;
    case rtclog2::BweProbeResultFailure::TIMEOUT:
      return ProbeFailureReason::kTimeout;
    case rtclog2::BweProbeResultFailure::UNKNOWN:
      break;
  }
  RTC_NOTREACHED();
  return ProbeFailureReason::kTimeout;
}

DtlsTransportState GetRuntimeDtlsTransportState(
    rtclog2::DtlsTransportStateEvent::DtlsTransportState state) {
  switch (state) {
    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_NEW:
      return DtlsTransportState::kNew;
    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTING:
      return DtlsTransportState::kConnecting;
    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTED:
      return DtlsTransportState::kConnected;
    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CLOSED:
      return DtlsTransportState::kClosed;
    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_FAILED:
      return DtlsTransportState::kFailed;
    case rtclog2::DtlsTransportStateEvent::UNKNOWN_DTLS_TRANSPORT_STATE:
      RTC_NOTREACHED();
      return DtlsTransportState::kNumValues;
  }
  RTC_NOTREACHED();
  return DtlsTransportState::kNumValues;
}

IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType(
    rtclog2::IceCandidatePairConfig::IceCandidatePairConfigType type) {
  switch (type) {
    case rtclog2::IceCandidatePairConfig::ADDED:
      return IceCandidatePairConfigType::kAdded;
    case rtclog2::IceCandidatePairConfig::UPDATED:
      return IceCandidatePairConfigType::kUpdated;
    case rtclog2::IceCandidatePairConfig::DESTROYED:
      return IceCandidatePairConfigType::kDestroyed;
    case rtclog2::IceCandidatePairConfig::SELECTED:
      return IceCandidatePairConfigType::kSelected;
    case rtclog2::IceCandidatePairConfig::UNKNOWN_CONFIG_TYPE:
      break;
  }
  RTC_NOTREACHED();
  return IceCandidatePairConfigType::kAdded;
}

IceCandidateType GetRuntimeIceCandidateType(
    rtclog2::IceCandidatePairConfig::IceCandidateType type) {
  switch (type) {
    case rtclog2::IceCandidatePairConfig::LOCAL:
      return IceCandidateType::kLocal;
    case rtclog2::IceCandidatePairConfig::STUN:
      return IceCandidateType::kStun;
    case rtclog2::IceCandidatePairConfig::PRFLX:
      return IceCandidateType::kPrflx;
    case rtclog2::IceCandidatePairConfig::RELAY:
      return IceCandidateType::kRelay;
    case rtclog2::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE:
      return IceCandidateType::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidateType::kUnknown;
}

IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
    rtclog2::IceCandidatePairConfig::Protocol protocol) {
  switch (protocol) {
    case rtclog2::IceCandidatePairConfig::UDP:
      return IceCandidatePairProtocol::kUdp;
    case rtclog2::IceCandidatePairConfig::TCP:
      return IceCandidatePairProtocol::kTcp;
    case rtclog2::IceCandidatePairConfig::SSLTCP:
      return IceCandidatePairProtocol::kSsltcp;
    case rtclog2::IceCandidatePairConfig::TLS:
      return IceCandidatePairProtocol::kTls;
    case rtclog2::IceCandidatePairConfig::UNKNOWN_PROTOCOL:
      return IceCandidatePairProtocol::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidatePairProtocol::kUnknown;
}

IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
    rtclog2::IceCandidatePairConfig::AddressFamily address_family) {
  switch (address_family) {
    case rtclog2::IceCandidatePairConfig::IPV4:
      return IceCandidatePairAddressFamily::kIpv4;
    case rtclog2::IceCandidatePairConfig::IPV6:
      return IceCandidatePairAddressFamily::kIpv6;
    case rtclog2::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY:
      return IceCandidatePairAddressFamily::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidatePairAddressFamily::kUnknown;
}

IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
    rtclog2::IceCandidatePairConfig::NetworkType network_type) {
  switch (network_type) {
    case rtclog2::IceCandidatePairConfig::ETHERNET:
      return IceCandidateNetworkType::kEthernet;
    case rtclog2::IceCandidatePairConfig::LOOPBACK:
      return IceCandidateNetworkType::kLoopback;
    case rtclog2::IceCandidatePairConfig::WIFI:
      return IceCandidateNetworkType::kWifi;
    case rtclog2::IceCandidatePairConfig::VPN:
      return IceCandidateNetworkType::kVpn;
    case rtclog2::IceCandidatePairConfig::CELLULAR:
      return IceCandidateNetworkType::kCellular;
    case rtclog2::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE:
      return IceCandidateNetworkType::kUnknown;
  }
  RTC_NOTREACHED();
  return IceCandidateNetworkType::kUnknown;
}

IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
    rtclog2::IceCandidatePairEvent::IceCandidatePairEventType type) {
  switch (type) {
    case rtclog2::IceCandidatePairEvent::CHECK_SENT:
      return IceCandidatePairEventType::kCheckSent;
    case rtclog2::IceCandidatePairEvent::CHECK_RECEIVED:
      return IceCandidatePairEventType::kCheckReceived;
    case rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_SENT:
      return IceCandidatePairEventType::kCheckResponseSent;
    case rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED:
      return IceCandidatePairEventType::kCheckResponseReceived;
    case rtclog2::IceCandidatePairEvent::UNKNOWN_CHECK_TYPE:
      break;
  }
  RTC_NOTREACHED();
  return IceCandidatePairEventType::kCheckSent;
}

std::vector<RtpExtension> GetRuntimeRtpHeaderExtensionConfig(
    const rtclog2::RtpHeaderExtensionConfig& proto_header_extensions) {
  std::vector<RtpExtension> rtp_extensions;
  if (proto_header_extensions.has_transmission_time_offset_id()) {
    rtp_extensions.emplace_back(
        RtpExtension::kTimestampOffsetUri,
        proto_header_extensions.transmission_time_offset_id());
  }
  if (proto_header_extensions.has_absolute_send_time_id()) {
    rtp_extensions.emplace_back(
        RtpExtension::kAbsSendTimeUri,
        proto_header_extensions.absolute_send_time_id());
  }
  if (proto_header_extensions.has_transport_sequence_number_id()) {
    rtp_extensions.emplace_back(
        RtpExtension::kTransportSequenceNumberUri,
        proto_header_extensions.transport_sequence_number_id());
  }
  if (proto_header_extensions.has_audio_level_id()) {
    rtp_extensions.emplace_back(RtpExtension::kAudioLevelUri,
                                proto_header_extensions.audio_level_id());
  }
  if (proto_header_extensions.has_video_rotation_id()) {
    rtp_extensions.emplace_back(RtpExtension::kVideoRotationUri,
                                proto_header_extensions.video_rotation_id());
  }
  return rtp_extensions;
}
// End of conversion functions.

ParsedRtcEventLog::~ParsedRtcEventLog() = default;

ParsedRtcEventLog::LoggedRtpStreamIncoming::LoggedRtpStreamIncoming() = default;
ParsedRtcEventLog::LoggedRtpStreamIncoming::LoggedRtpStreamIncoming(
    const LoggedRtpStreamIncoming& rhs) = default;
ParsedRtcEventLog::LoggedRtpStreamIncoming::~LoggedRtpStreamIncoming() =
    default;

ParsedRtcEventLog::LoggedRtpStreamOutgoing::LoggedRtpStreamOutgoing() = default;
ParsedRtcEventLog::LoggedRtpStreamOutgoing::LoggedRtpStreamOutgoing(
    const LoggedRtpStreamOutgoing& rhs) = default;
ParsedRtcEventLog::LoggedRtpStreamOutgoing::~LoggedRtpStreamOutgoing() =
    default;

ParsedRtcEventLog::LoggedRtpStreamView::LoggedRtpStreamView(
    uint32_t ssrc,
    const std::vector<LoggedRtpPacketIncoming>& packets)
    : ssrc(ssrc), packet_view() {
  for (const LoggedRtpPacketIncoming& packet : packets) {
    packet_view.push_back(&(packet.rtp));
  }
}

ParsedRtcEventLog::LoggedRtpStreamView::LoggedRtpStreamView(
    uint32_t ssrc,
    const std::vector<LoggedRtpPacketOutgoing>& packets)
    : ssrc(ssrc), packet_view() {
  for (const LoggedRtpPacketOutgoing& packet : packets) {
    packet_view.push_back(&(packet.rtp));
  }
}

ParsedRtcEventLog::LoggedRtpStreamView::LoggedRtpStreamView(
    const LoggedRtpStreamView&) = default;

// Return default values for header extensions, to use on streams without stored
// mapping data. Currently this only applies to audio streams, since the mapping
// is not stored in the event log.
// TODO(ivoc): Remove this once this mapping is stored in the event log for
//             audio streams. Tracking bug: webrtc:6399
webrtc::RtpHeaderExtensionMap
ParsedRtcEventLog::GetDefaultHeaderExtensionMap() {
  // Values from before the default RTP header extension IDs were removed.
  constexpr int kAudioLevelDefaultId = 1;
  constexpr int kTimestampOffsetDefaultId = 2;
  constexpr int kAbsSendTimeDefaultId = 3;
  constexpr int kVideoRotationDefaultId = 4;
  constexpr int kTransportSequenceNumberDefaultId = 5;
  constexpr int kPlayoutDelayDefaultId = 6;
  constexpr int kVideoContentTypeDefaultId = 7;
  constexpr int kVideoTimingDefaultId = 8;

  webrtc::RtpHeaderExtensionMap default_map;
  default_map.Register<AudioLevel>(kAudioLevelDefaultId);
  default_map.Register<TransmissionOffset>(kTimestampOffsetDefaultId);
  default_map.Register<AbsoluteSendTime>(kAbsSendTimeDefaultId);
  default_map.Register<VideoOrientation>(kVideoRotationDefaultId);
  default_map.Register<TransportSequenceNumber>(
      kTransportSequenceNumberDefaultId);
  default_map.Register<PlayoutDelayLimits>(kPlayoutDelayDefaultId);
  default_map.Register<VideoContentTypeExtension>(kVideoContentTypeDefaultId);
  default_map.Register<VideoTimingExtension>(kVideoTimingDefaultId);
  return default_map;
}

ParsedRtcEventLog::ParsedRtcEventLog(
    UnconfiguredHeaderExtensions parse_unconfigured_header_extensions,
    bool allow_incomplete_logs)
    : parse_unconfigured_header_extensions_(
          parse_unconfigured_header_extensions),
      allow_incomplete_logs_(allow_incomplete_logs) {
  Clear();
}

void ParsedRtcEventLog::Clear() {
  default_extension_map_ = GetDefaultHeaderExtensionMap();

  incoming_rtx_ssrcs_.clear();
  incoming_video_ssrcs_.clear();
  incoming_audio_ssrcs_.clear();
  outgoing_rtx_ssrcs_.clear();
  outgoing_video_ssrcs_.clear();
  outgoing_audio_ssrcs_.clear();

  incoming_rtp_packets_map_.clear();
  outgoing_rtp_packets_map_.clear();
  incoming_rtp_packets_by_ssrc_.clear();
  outgoing_rtp_packets_by_ssrc_.clear();
  incoming_rtp_packet_views_by_ssrc_.clear();
  outgoing_rtp_packet_views_by_ssrc_.clear();

  incoming_rtcp_packets_.clear();
  outgoing_rtcp_packets_.clear();

  incoming_rr_.clear();
  outgoing_rr_.clear();
  incoming_sr_.clear();
  outgoing_sr_.clear();
  incoming_nack_.clear();
  outgoing_nack_.clear();
  incoming_remb_.clear();
  outgoing_remb_.clear();
  incoming_transport_feedback_.clear();
  outgoing_transport_feedback_.clear();
  incoming_loss_notification_.clear();
  outgoing_loss_notification_.clear();

  start_log_events_.clear();
  stop_log_events_.clear();
  audio_playout_events_.clear();
  audio_network_adaptation_events_.clear();
  bwe_probe_cluster_created_events_.clear();
  bwe_probe_failure_events_.clear();
  bwe_probe_success_events_.clear();
  bwe_delay_updates_.clear();
  bwe_loss_updates_.clear();
  dtls_transport_states_.clear();
  dtls_writable_states_.clear();
  decoded_frames_.clear();
  alr_state_events_.clear();
  ice_candidate_pair_configs_.clear();
  ice_candidate_pair_events_.clear();
  audio_recv_configs_.clear();
  audio_send_configs_.clear();
  video_recv_configs_.clear();
  video_send_configs_.clear();

  last_incoming_rtcp_packet_.clear();

  first_timestamp_ = std::numeric_limits<int64_t>::max();
  last_timestamp_ = std::numeric_limits<int64_t>::min();
  first_log_segment_ = LogSegment(0, std::numeric_limits<int64_t>::max());

  incoming_rtp_extensions_maps_.clear();
  outgoing_rtp_extensions_maps_.clear();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseFile(
    const std::string& filename) {
  FileWrapper file = FileWrapper::OpenReadOnly(filename);
  if (!file.is_open()) {
    RTC_LOG(LS_WARNING) << "Could not open file " << filename
                        << " for reading.";
    RTC_PARSE_CHECK_OR_RETURN(file.is_open());
  }

  // Compute file size.
  long signed_filesize = file.FileSize();  // NOLINT(runtime/int)
  RTC_PARSE_CHECK_OR_RETURN_GE(signed_filesize, 0);
  RTC_PARSE_CHECK_OR_RETURN_LE(signed_filesize, kMaxLogSize);
  size_t filesize = rtc::checked_cast<size_t>(signed_filesize);

  // Read file into memory.
  std::string buffer(filesize, '\0');
  size_t bytes_read = file.Read(&buffer[0], buffer.size());
  if (bytes_read != filesize) {
    RTC_LOG(LS_WARNING) << "Failed to read file " << filename;
    RTC_PARSE_CHECK_OR_RETURN_EQ(bytes_read, filesize);
  }

  return ParseStream(buffer);
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseString(
    const std::string& s) {
  return ParseStream(s);
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStream(
    const std::string& s) {
  Clear();
  ParseStatus status = ParseStreamInternal(s);

  // Cache the configured SSRCs.
  for (const auto& video_recv_config : video_recv_configs()) {
    incoming_video_ssrcs_.insert(video_recv_config.config.remote_ssrc);
    incoming_video_ssrcs_.insert(video_recv_config.config.rtx_ssrc);
    incoming_rtx_ssrcs_.insert(video_recv_config.config.rtx_ssrc);
  }
  for (const auto& video_send_config : video_send_configs()) {
    outgoing_video_ssrcs_.insert(video_send_config.config.local_ssrc);
    outgoing_video_ssrcs_.insert(video_send_config.config.rtx_ssrc);
    outgoing_rtx_ssrcs_.insert(video_send_config.config.rtx_ssrc);
  }
  for (const auto& audio_recv_config : audio_recv_configs()) {
    incoming_audio_ssrcs_.insert(audio_recv_config.config.remote_ssrc);
  }
  for (const auto& audio_send_config : audio_send_configs()) {
    outgoing_audio_ssrcs_.insert(audio_send_config.config.local_ssrc);
  }

  // ParseStreamInternal stores the RTP packets in a map indexed by SSRC.
  // Since we dont need rapid lookup based on SSRC after parsing, we move the
  // packets_streams from map to vector.
  incoming_rtp_packets_by_ssrc_.reserve(incoming_rtp_packets_map_.size());
  for (auto& kv : incoming_rtp_packets_map_) {
    incoming_rtp_packets_by_ssrc_.emplace_back(LoggedRtpStreamIncoming());
    incoming_rtp_packets_by_ssrc_.back().ssrc = kv.first;
    incoming_rtp_packets_by_ssrc_.back().incoming_packets =
        std::move(kv.second);
  }
  incoming_rtp_packets_map_.clear();
  outgoing_rtp_packets_by_ssrc_.reserve(outgoing_rtp_packets_map_.size());
  for (auto& kv : outgoing_rtp_packets_map_) {
    outgoing_rtp_packets_by_ssrc_.emplace_back(LoggedRtpStreamOutgoing());
    outgoing_rtp_packets_by_ssrc_.back().ssrc = kv.first;
    outgoing_rtp_packets_by_ssrc_.back().outgoing_packets =
        std::move(kv.second);
  }
  outgoing_rtp_packets_map_.clear();

  // Build PacketViews for easier iteration over RTP packets.
  for (const auto& stream : incoming_rtp_packets_by_ssrc_) {
    incoming_rtp_packet_views_by_ssrc_.emplace_back(
        LoggedRtpStreamView(stream.ssrc, stream.incoming_packets));
  }
  for (const auto& stream : outgoing_rtp_packets_by_ssrc_) {
    outgoing_rtp_packet_views_by_ssrc_.emplace_back(
        LoggedRtpStreamView(stream.ssrc, stream.outgoing_packets));
  }

  // Set up convenience wrappers around the most commonly used RTCP types.
  for (const auto& incoming : incoming_rtcp_packets_) {
    const int64_t timestamp_us = incoming.rtcp.timestamp.us();
    const uint8_t* packet_begin = incoming.rtcp.raw_data.data();
    const uint8_t* packet_end = packet_begin + incoming.rtcp.raw_data.size();
    auto status = StoreRtcpBlocks(
        timestamp_us, packet_begin, packet_end, &incoming_sr_, &incoming_rr_,
        &incoming_xr_, &incoming_remb_, &incoming_nack_, &incoming_fir_,
        &incoming_pli_, &incoming_bye_, &incoming_transport_feedback_,
        &incoming_loss_notification_);
    RTC_RETURN_IF_ERROR(status);
  }

  for (const auto& outgoing : outgoing_rtcp_packets_) {
    const int64_t timestamp_us = outgoing.rtcp.timestamp.us();
    const uint8_t* packet_begin = outgoing.rtcp.raw_data.data();
    const uint8_t* packet_end = packet_begin + outgoing.rtcp.raw_data.size();
    auto status = StoreRtcpBlocks(
        timestamp_us, packet_begin, packet_end, &outgoing_sr_, &outgoing_rr_,
        &outgoing_xr_, &outgoing_remb_, &outgoing_nack_, &outgoing_fir_,
        &outgoing_pli_, &outgoing_bye_, &outgoing_transport_feedback_,
        &outgoing_loss_notification_);
    RTC_RETURN_IF_ERROR(status);
  }

  // Store first and last timestamp events that might happen before the call is
  // connected or after the call is disconnected. Typical examples are
  // stream configurations and starting/stopping the log.
  // TODO(terelius): Figure out if we actually need to find the first and last
  // timestamp in the parser. It seems like this could be done by the caller.
  first_timestamp_ = std::numeric_limits<int64_t>::max();
  last_timestamp_ = std::numeric_limits<int64_t>::min();
  StoreFirstAndLastTimestamp(alr_state_events());
  StoreFirstAndLastTimestamp(route_change_events());
  for (const auto& audio_stream : audio_playout_events()) {
    // Audio playout events are grouped by SSRC.
    StoreFirstAndLastTimestamp(audio_stream.second);
  }
  StoreFirstAndLastTimestamp(audio_network_adaptation_events());
  StoreFirstAndLastTimestamp(bwe_probe_cluster_created_events());
  StoreFirstAndLastTimestamp(bwe_probe_failure_events());
  StoreFirstAndLastTimestamp(bwe_probe_success_events());
  StoreFirstAndLastTimestamp(bwe_delay_updates());
  StoreFirstAndLastTimestamp(bwe_loss_updates());
  for (const auto& frame_stream : decoded_frames()) {
    StoreFirstAndLastTimestamp(frame_stream.second);
  }
  StoreFirstAndLastTimestamp(dtls_transport_states());
  StoreFirstAndLastTimestamp(dtls_writable_states());
  StoreFirstAndLastTimestamp(ice_candidate_pair_configs());
  StoreFirstAndLastTimestamp(ice_candidate_pair_events());
  for (const auto& rtp_stream : incoming_rtp_packets_by_ssrc()) {
    StoreFirstAndLastTimestamp(rtp_stream.incoming_packets);
  }
  for (const auto& rtp_stream : outgoing_rtp_packets_by_ssrc()) {
    StoreFirstAndLastTimestamp(rtp_stream.outgoing_packets);
  }
  StoreFirstAndLastTimestamp(incoming_rtcp_packets());
  StoreFirstAndLastTimestamp(outgoing_rtcp_packets());
  StoreFirstAndLastTimestamp(generic_packets_sent_);
  StoreFirstAndLastTimestamp(generic_packets_received_);
  StoreFirstAndLastTimestamp(generic_acks_received_);
  StoreFirstAndLastTimestamp(remote_estimate_events_);

  // Stop events could be missing due to file size limits. If so, use the
  // last event, or the next start timestamp if available.
  // TODO(terelius): This could be improved. Instead of using the next start
  // event, we could use the timestamp of the the last previous regular event.
  auto start_iter = start_log_events().begin();
  auto stop_iter = stop_log_events().begin();
  int64_t start_us = first_timestamp();
  int64_t next_start_us = std::numeric_limits<int64_t>::max();
  int64_t stop_us = std::numeric_limits<int64_t>::max();
  if (start_iter != start_log_events().end()) {
    start_us = std::min(start_us, start_iter->log_time_us());
    ++start_iter;
    if (start_iter != start_log_events().end())
      next_start_us = start_iter->log_time_us();
  }
  if (stop_iter != stop_log_events().end()) {
    stop_us = stop_iter->log_time_us();
  }
  stop_us = std::min(stop_us, next_start_us);
  if (stop_us == std::numeric_limits<int64_t>::max() &&
      last_timestamp() != std::numeric_limits<int64_t>::min()) {
    stop_us = last_timestamp();
  }
  RTC_PARSE_CHECK_OR_RETURN_LE(start_us, stop_us);
  first_log_segment_ = LogSegment(start_us, stop_us);

  if (first_timestamp_ == std::numeric_limits<int64_t>::max() &&
      last_timestamp_ == std::numeric_limits<int64_t>::min()) {
    first_timestamp_ = last_timestamp_ = 0;
  }

  return status;
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStreamInternal(
    absl::string_view s) {
  constexpr uint64_t kMaxEventSize = 10000000;  // Sanity check.

  while (!s.empty()) {
    absl::string_view event_start = s;
    bool success = false;

    // Read the next message tag. Protobuf defines the message tag as
    // (field_number << 3) | wire_type. In the legacy encoding, the field number
    // is supposed to be 1 and the wire type for a length-delimited field is 2.
    // In the new encoding we still expect the wire type to be 2, but the field
    // number will be greater than 1.
    constexpr uint64_t kExpectedV1Tag = (1 << 3) | 2;
    uint64_t tag = 0;
    std::tie(success, s) = DecodeVarInt(s, &tag);
    if (!success) {
      RTC_LOG(LS_WARNING)
          << "Failed to read field tag from beginning of protobuf event.";
      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
                                           kIncompleteLogError);
      return ParseStatus::Error("Failed to read field tag varint", __FILE__,
                                __LINE__);
    }
    constexpr uint64_t kWireTypeMask = 0x07;
    const uint64_t wire_type = tag & kWireTypeMask;
    if (wire_type != 2) {
      RTC_LOG(LS_WARNING) << "Expected field tag with wire type 2 (length "
                             "delimited message). Found wire type "
                          << wire_type;
      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
                                           kIncompleteLogError);
      RTC_PARSE_CHECK_OR_RETURN_EQ(wire_type, 2);
    }

    // Read the length field.
    uint64_t message_length = 0;
    std::tie(success, s) = DecodeVarInt(s, &message_length);
    if (!success) {
      RTC_LOG(LS_WARNING) << "Missing message length after protobuf field tag.";
      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
                                           kIncompleteLogError);
      return ParseStatus::Error("Failed to read message length varint",
                                __FILE__, __LINE__);
    }

    if (message_length > s.size()) {
      RTC_LOG(LS_WARNING) << "Protobuf message length is larger than the "
                             "remaining bytes in the proto.";
      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
                                           kIncompleteLogError);
      return ParseStatus::Error(
          "Incomplete message: the length of the next message is larger than "
          "the remaining bytes in the proto",
          __FILE__, __LINE__);
    }

    RTC_PARSE_CHECK_OR_RETURN_LE(message_length, kMaxEventSize);
    // Skip forward to the start of the next event.
    s = s.substr(message_length);
    size_t total_event_size = event_start.size() - s.size();
    RTC_CHECK_LE(total_event_size, event_start.size());

    if (tag == kExpectedV1Tag) {
      // Parse the protobuf event from the buffer.
      rtclog::EventStream event_stream;
      if (!event_stream.ParseFromArray(event_start.data(), total_event_size)) {
        RTC_LOG(LS_WARNING)
            << "Failed to parse legacy-format protobuf message.";
        RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
                                             kIncompleteLogError);
        RTC_PARSE_CHECK_OR_RETURN(false);
      }

      RTC_PARSE_CHECK_OR_RETURN_EQ(event_stream.stream_size(), 1);
      auto status = StoreParsedLegacyEvent(event_stream.stream(0));
      RTC_RETURN_IF_ERROR(status);
    } else {
      // Parse the protobuf event from the buffer.
      rtclog2::EventStream event_stream;
      if (!event_stream.ParseFromArray(event_start.data(), total_event_size)) {
        RTC_LOG(LS_WARNING) << "Failed to parse new-format protobuf message.";
        RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
                                             kIncompleteLogError);
        RTC_PARSE_CHECK_OR_RETURN(false);
      }
      auto status = StoreParsedNewFormatEvent(event_stream);
      RTC_RETURN_IF_ERROR(status);
    }
  }
  return ParseStatus::Success();
}

template <typename T>
void ParsedRtcEventLog::StoreFirstAndLastTimestamp(const std::vector<T>& v) {
  if (v.empty())
    return;
  first_timestamp_ = std::min(first_timestamp_, v.front().log_time_us());
  last_timestamp_ = std::max(last_timestamp_, v.back().log_time_us());
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedLegacyEvent(
    const rtclog::Event& event) {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  switch (event.type()) {
    case rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT: {
      auto config = GetVideoReceiveConfig(event);
      if (!config.ok())
        return config.status();

      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      video_recv_configs_.emplace_back(Timestamp::Micros(timestamp_us),
                                       config.value());
      incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
          RtpHeaderExtensionMap(config.value().rtp_extensions);
      incoming_rtp_extensions_maps_[config.value().rtx_ssrc] =
          RtpHeaderExtensionMap(config.value().rtp_extensions);
      break;
    }
    case rtclog::Event::VIDEO_SENDER_CONFIG_EVENT: {
      auto config = GetVideoSendConfig(event);
      if (!config.ok())
        return config.status();

      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      video_send_configs_.emplace_back(Timestamp::Micros(timestamp_us),
                                       config.value());
      outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
          RtpHeaderExtensionMap(config.value().rtp_extensions);
      outgoing_rtp_extensions_maps_[config.value().rtx_ssrc] =
          RtpHeaderExtensionMap(config.value().rtp_extensions);
      break;
    }
    case rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT: {
      auto config = GetAudioReceiveConfig(event);
      if (!config.ok())
        return config.status();

      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      audio_recv_configs_.emplace_back(Timestamp::Micros(timestamp_us),
                                       config.value());
      incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
          RtpHeaderExtensionMap(config.value().rtp_extensions);
      break;
    }
    case rtclog::Event::AUDIO_SENDER_CONFIG_EVENT: {
      auto config = GetAudioSendConfig(event);
      if (!config.ok())
        return config.status();
      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      audio_send_configs_.emplace_back(Timestamp::Micros(timestamp_us),
                                       config.value());
      outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
          RtpHeaderExtensionMap(config.value().rtp_extensions);
      break;
    }
    case rtclog::Event::RTP_EVENT: {
      PacketDirection direction;
      uint8_t header[IP_PACKET_SIZE];
      size_t header_length;
      size_t total_length;
      ParseStatus status = GetRtpHeader(event, &direction, header,
                                        &header_length, &total_length, nullptr);
      RTC_RETURN_IF_ERROR(status);

      uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(header + 8);
      const RtpHeaderExtensionMap* extension_map =
          GetRtpHeaderExtensionMap(direction, ssrc);
      RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
      RTPHeader parsed_header;
      rtp_parser.Parse(&parsed_header, extension_map, /*header_only*/ true);

      // Since we give the parser only a header, there is no way for it to know
      // the padding length. The best solution would be to log the padding
      // length in RTC event log. In absence of it, we assume the RTP packet to
      // contain only padding, if the padding bit is set.
      // TODO(webrtc:9730): Use a generic way to obtain padding length.
      if ((header[0] & 0x20) != 0)
        parsed_header.paddingLength = total_length - header_length;

      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      if (direction == kIncomingPacket) {
        incoming_rtp_packets_map_[parsed_header.ssrc].push_back(
            LoggedRtpPacketIncoming(Timestamp::Micros(timestamp_us),
                                    parsed_header, header_length,
                                    total_length));
      } else {
        outgoing_rtp_packets_map_[parsed_header.ssrc].push_back(
            LoggedRtpPacketOutgoing(Timestamp::Micros(timestamp_us),
                                    parsed_header, header_length,
                                    total_length));
      }
      break;
    }
    case rtclog::Event::RTCP_EVENT: {
      PacketDirection direction;
      std::vector<uint8_t> packet;
      auto status = GetRtcpPacket(event, &direction, &packet);
      RTC_RETURN_IF_ERROR(status);
      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      if (direction == kIncomingPacket) {
        // Currently incoming RTCP packets are logged twice, both for audio and
        // video. Only act on one of them. Compare against the previous parsed
        // incoming RTCP packet.
        if (packet == last_incoming_rtcp_packet_)
          break;
        incoming_rtcp_packets_.push_back(
            LoggedRtcpPacketIncoming(Timestamp::Micros(timestamp_us), packet));
        last_incoming_rtcp_packet_ = packet;
      } else {
        outgoing_rtcp_packets_.push_back(
            LoggedRtcpPacketOutgoing(Timestamp::Micros(timestamp_us), packet));
      }
      break;
    }
    case rtclog::Event::LOG_START: {
      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      start_log_events_.push_back(
          LoggedStartEvent(Timestamp::Micros(timestamp_us)));
      break;
    }
    case rtclog::Event::LOG_END: {
      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
      int64_t timestamp_us = event.timestamp_us();
      stop_log_events_.push_back(
          LoggedStopEvent(Timestamp::Micros(timestamp_us)));
      break;
    }
    case rtclog::Event::AUDIO_PLAYOUT_EVENT: {
      auto status_or_value = GetAudioPlayout(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      LoggedAudioPlayoutEvent playout_event = status_or_value.value();
      audio_playout_events_[playout_event.ssrc].push_back(playout_event);
      break;
    }
    case rtclog::Event::LOSS_BASED_BWE_UPDATE: {
      auto status_or_value = GetLossBasedBweUpdate(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      bwe_loss_updates_.push_back(status_or_value.value());
      break;
    }
    case rtclog::Event::DELAY_BASED_BWE_UPDATE: {
      auto status_or_value = GetDelayBasedBweUpdate(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      bwe_delay_updates_.push_back(status_or_value.value());
      break;
    }
    case rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT: {
      auto status_or_value = GetAudioNetworkAdaptation(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      LoggedAudioNetworkAdaptationEvent ana_event = status_or_value.value();
      audio_network_adaptation_events_.push_back(ana_event);
      break;
    }
    case rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT: {
      auto status_or_value = GetBweProbeClusterCreated(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      bwe_probe_cluster_created_events_.push_back(status_or_value.value());
      break;
    }
    case rtclog::Event::BWE_PROBE_RESULT_EVENT: {
      // Probe successes and failures are currently stored in the same proto
      // message, we are moving towards separate messages. Probe results
      // therefore need special treatment in the parser.
      RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
      RTC_PARSE_CHECK_OR_RETURN(event.probe_result().has_result());
      if (event.probe_result().result() == rtclog::BweProbeResult::SUCCESS) {
        auto status_or_value = GetBweProbeSuccess(event);
        RTC_RETURN_IF_ERROR(status_or_value.status());
        bwe_probe_success_events_.push_back(status_or_value.value());
      } else {
        auto status_or_value = GetBweProbeFailure(event);
        RTC_RETURN_IF_ERROR(status_or_value.status());
        bwe_probe_failure_events_.push_back(status_or_value.value());
      }
      break;
    }
    case rtclog::Event::ALR_STATE_EVENT: {
      auto status_or_value = GetAlrState(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      alr_state_events_.push_back(status_or_value.value());
      break;
    }
    case rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG: {
      auto status_or_value = GetIceCandidatePairConfig(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      ice_candidate_pair_configs_.push_back(status_or_value.value());
      break;
    }
    case rtclog::Event::ICE_CANDIDATE_PAIR_EVENT: {
      auto status_or_value = GetIceCandidatePairEvent(event);
      RTC_RETURN_IF_ERROR(status_or_value.status());
      ice_candidate_pair_events_.push_back(status_or_value.value());
      break;
    }
    case rtclog::Event::UNKNOWN_EVENT: {
      break;
    }
  }
  return ParseStatus::Success();
}

// The header must have space for at least IP_PACKET_SIZE bytes.
ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::GetRtpHeader(
    const rtclog::Event& event,
    PacketDirection* incoming,
    uint8_t* header,
    size_t* header_length,
    size_t* total_length,
    int* probe_cluster_id) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::RTP_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_rtp_packet());
  const rtclog::RtpPacket& rtp_packet = event.rtp_packet();
  // Get direction of packet.
  RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_incoming());
  if (incoming != nullptr) {
    *incoming = rtp_packet.incoming() ? kIncomingPacket : kOutgoingPacket;
  }
  // Get packet length.
  RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_packet_length());
  if (total_length != nullptr) {
    *total_length = rtp_packet.packet_length();
  }
  // Get header length.
  RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_header());
  if (header_length != nullptr) {
    *header_length = rtp_packet.header().size();
  }
  if (probe_cluster_id != nullptr) {
    if (rtp_packet.has_probe_cluster_id()) {
      *probe_cluster_id = rtp_packet.probe_cluster_id();
      RTC_PARSE_CHECK_OR_RETURN_NE(*probe_cluster_id,
                                   PacedPacketInfo::kNotAProbe);
    } else {
      *probe_cluster_id = PacedPacketInfo::kNotAProbe;
    }
  }
  // Get header contents.
  if (header != nullptr) {
    const size_t kMinRtpHeaderSize = 12;
    RTC_PARSE_CHECK_OR_RETURN_GE(rtp_packet.header().size(), kMinRtpHeaderSize);
    RTC_PARSE_CHECK_OR_RETURN_LE(rtp_packet.header().size(),
                                 static_cast<size_t>(IP_PACKET_SIZE));
    memcpy(header, rtp_packet.header().data(), rtp_packet.header().size());
  }
  return ParseStatus::Success();
}

const RtpHeaderExtensionMap* ParsedRtcEventLog::GetRtpHeaderExtensionMap(
    PacketDirection direction,
    uint32_t ssrc) {
  auto& extensions_maps = direction == PacketDirection::kIncomingPacket
                              ? incoming_rtp_extensions_maps_
                              : outgoing_rtp_extensions_maps_;
  auto it = extensions_maps.find(ssrc);
  if (it != extensions_maps.end()) {
    return &(it->second);
  }
  if (parse_unconfigured_header_extensions_ ==
      UnconfiguredHeaderExtensions::kAttemptWebrtcDefaultConfig) {
    RTC_LOG(LS_WARNING) << "Using default header extension map for SSRC "
                        << ssrc;
    extensions_maps.insert(std::make_pair(ssrc, default_extension_map_));
    return &default_extension_map_;
  }
  RTC_LOG(LS_WARNING) << "Not parsing header extensions for SSRC " << ssrc
                      << ". No header extension map found.";
  return nullptr;
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::GetRtcpPacket(
    const rtclog::Event& event,
    PacketDirection* incoming,
    std::vector<uint8_t>* packet) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::RTCP_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_rtcp_packet());
  const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet();
  // Get direction of packet.
  RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_incoming());
  if (incoming != nullptr) {
    *incoming = rtcp_packet.incoming() ? kIncomingPacket : kOutgoingPacket;
  }
  // Get packet contents.
  RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_packet_data());
  if (packet != nullptr) {
    packet->resize(rtcp_packet.packet_data().size());
    memcpy(packet->data(), rtcp_packet.packet_data().data(),
           rtcp_packet.packet_data().size());
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
ParsedRtcEventLog::GetVideoReceiveConfig(const rtclog::Event& event) const {
  rtclog::StreamConfig config;
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_video_receiver_config());
  const rtclog::VideoReceiveConfig& receiver_config =
      event.video_receiver_config();
  // Get SSRCs.
  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remote_ssrc());
  config.remote_ssrc = receiver_config.remote_ssrc();
  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_local_ssrc());
  config.local_ssrc = receiver_config.local_ssrc();
  config.rtx_ssrc = 0;
  // Get RTCP settings.
  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_rtcp_mode());
  config.rtcp_mode = GetRuntimeRtcpMode(receiver_config.rtcp_mode());
  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remb());
  config.remb = receiver_config.remb();

  // Get RTX map.
  std::map<uint32_t, const rtclog::RtxConfig> rtx_map;
  for (int i = 0; i < receiver_config.rtx_map_size(); i++) {
    const rtclog::RtxMap& map = receiver_config.rtx_map(i);
    RTC_PARSE_CHECK_OR_RETURN(map.has_payload_type());
    RTC_PARSE_CHECK_OR_RETURN(map.has_config());
    RTC_PARSE_CHECK_OR_RETURN(map.config().has_rtx_ssrc());
    RTC_PARSE_CHECK_OR_RETURN(map.config().has_rtx_payload_type());
    rtx_map.insert(std::make_pair(map.payload_type(), map.config()));
  }

  // Get header extensions.
  auto status = GetHeaderExtensions(&config.rtp_extensions,
                                    receiver_config.header_extensions());
  RTC_RETURN_IF_ERROR(status);

  // Get decoders.
  config.codecs.clear();
  for (int i = 0; i < receiver_config.decoders_size(); i++) {
    RTC_PARSE_CHECK_OR_RETURN(receiver_config.decoders(i).has_name());
    RTC_PARSE_CHECK_OR_RETURN(receiver_config.decoders(i).has_payload_type());
    int rtx_payload_type = 0;
    auto rtx_it = rtx_map.find(receiver_config.decoders(i).payload_type());
    if (rtx_it != rtx_map.end()) {
      rtx_payload_type = rtx_it->second.rtx_payload_type();
      if (config.rtx_ssrc != 0 &&
          config.rtx_ssrc != rtx_it->second.rtx_ssrc()) {
        RTC_LOG(LS_WARNING)
            << "RtcEventLog protobuf contained different SSRCs for "
               "different received RTX payload types. Will only use "
               "rtx_ssrc = "
            << config.rtx_ssrc << ".";
      } else {
        config.rtx_ssrc = rtx_it->second.rtx_ssrc();
      }
    }
    config.codecs.emplace_back(receiver_config.decoders(i).name(),
                               receiver_config.decoders(i).payload_type(),
                               rtx_payload_type);
  }
  return config;
}

ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
ParsedRtcEventLog::GetVideoSendConfig(const rtclog::Event& event) const {
  rtclog::StreamConfig config;
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_video_sender_config());
  const rtclog::VideoSendConfig& sender_config = event.video_sender_config();

  // Get SSRCs.
  // VideoSendStreamConfig no longer stores multiple SSRCs. If you are
  // analyzing a very old log, try building the parser from the same
  // WebRTC version.
  RTC_PARSE_CHECK_OR_RETURN_EQ(sender_config.ssrcs_size(), 1);
  config.local_ssrc = sender_config.ssrcs(0);
  RTC_PARSE_CHECK_OR_RETURN_LE(sender_config.rtx_ssrcs_size(), 1);
  if (sender_config.rtx_ssrcs_size() == 1) {
    config.rtx_ssrc = sender_config.rtx_ssrcs(0);
  }

  // Get header extensions.
  auto status = GetHeaderExtensions(&config.rtp_extensions,
                                    sender_config.header_extensions());
  RTC_RETURN_IF_ERROR(status);

  // Get the codec.
  RTC_PARSE_CHECK_OR_RETURN(sender_config.has_encoder());
  RTC_PARSE_CHECK_OR_RETURN(sender_config.encoder().has_name());
  RTC_PARSE_CHECK_OR_RETURN(sender_config.encoder().has_payload_type());
  config.codecs.emplace_back(
      sender_config.encoder().name(), sender_config.encoder().payload_type(),
      sender_config.has_rtx_payload_type() ? sender_config.rtx_payload_type()
                                           : 0);
  return config;
}

ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
ParsedRtcEventLog::GetAudioReceiveConfig(const rtclog::Event& event) const {
  rtclog::StreamConfig config;
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_receiver_config());
  const rtclog::AudioReceiveConfig& receiver_config =
      event.audio_receiver_config();
  // Get SSRCs.
  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remote_ssrc());
  config.remote_ssrc = receiver_config.remote_ssrc();
  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_local_ssrc());
  config.local_ssrc = receiver_config.local_ssrc();
  // Get header extensions.
  auto status = GetHeaderExtensions(&config.rtp_extensions,
                                    receiver_config.header_extensions());
  RTC_RETURN_IF_ERROR(status);

  return config;
}

ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
ParsedRtcEventLog::GetAudioSendConfig(const rtclog::Event& event) const {
  rtclog::StreamConfig config;
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::AUDIO_SENDER_CONFIG_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_sender_config());
  const rtclog::AudioSendConfig& sender_config = event.audio_sender_config();
  // Get SSRCs.
  RTC_PARSE_CHECK_OR_RETURN(sender_config.has_ssrc());
  config.local_ssrc = sender_config.ssrc();
  // Get header extensions.
  auto status = GetHeaderExtensions(&config.rtp_extensions,
                                    sender_config.header_extensions());
  RTC_RETURN_IF_ERROR(status);

  return config;
}

ParsedRtcEventLog::ParseStatusOr<LoggedAudioPlayoutEvent>
ParsedRtcEventLog::GetAudioPlayout(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::AUDIO_PLAYOUT_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_playout_event());
  const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event();
  LoggedAudioPlayoutEvent res;
  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(playout_event.has_local_ssrc());
  res.ssrc = playout_event.local_ssrc();
  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedBweLossBasedUpdate>
ParsedRtcEventLog::GetLossBasedBweUpdate(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::LOSS_BASED_BWE_UPDATE);
  RTC_PARSE_CHECK_OR_RETURN(event.has_loss_based_bwe_update());
  const rtclog::LossBasedBweUpdate& loss_event = event.loss_based_bwe_update();

  LoggedBweLossBasedUpdate bwe_update;
  RTC_CHECK(event.has_timestamp_us());
  bwe_update.timestamp = Timestamp::Micros(event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(loss_event.has_bitrate_bps());
  bwe_update.bitrate_bps = loss_event.bitrate_bps();
  RTC_PARSE_CHECK_OR_RETURN(loss_event.has_fraction_loss());
  bwe_update.fraction_lost = loss_event.fraction_loss();
  RTC_PARSE_CHECK_OR_RETURN(loss_event.has_total_packets());
  bwe_update.expected_packets = loss_event.total_packets();
  return bwe_update;
}

ParsedRtcEventLog::ParseStatusOr<LoggedBweDelayBasedUpdate>
ParsedRtcEventLog::GetDelayBasedBweUpdate(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::DELAY_BASED_BWE_UPDATE);
  RTC_PARSE_CHECK_OR_RETURN(event.has_delay_based_bwe_update());
  const rtclog::DelayBasedBweUpdate& delay_event =
      event.delay_based_bwe_update();

  LoggedBweDelayBasedUpdate res;
  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(delay_event.has_bitrate_bps());
  res.bitrate_bps = delay_event.bitrate_bps();
  RTC_PARSE_CHECK_OR_RETURN(delay_event.has_detector_state());
  res.detector_state = GetRuntimeDetectorState(delay_event.detector_state());
  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedAudioNetworkAdaptationEvent>
ParsedRtcEventLog::GetAudioNetworkAdaptation(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_network_adaptation());
  const rtclog::AudioNetworkAdaptation& ana_event =
      event.audio_network_adaptation();

  LoggedAudioNetworkAdaptationEvent res;
  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(event.timestamp_us());
  if (ana_event.has_bitrate_bps())
    res.config.bitrate_bps = ana_event.bitrate_bps();
  if (ana_event.has_enable_fec())
    res.config.enable_fec = ana_event.enable_fec();
  if (ana_event.has_enable_dtx())
    res.config.enable_dtx = ana_event.enable_dtx();
  if (ana_event.has_frame_length_ms())
    res.config.frame_length_ms = ana_event.frame_length_ms();
  if (ana_event.has_num_channels())
    res.config.num_channels = ana_event.num_channels();
  if (ana_event.has_uplink_packet_loss_fraction())
    res.config.uplink_packet_loss_fraction =
        ana_event.uplink_packet_loss_fraction();
  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeClusterCreatedEvent>
ParsedRtcEventLog::GetBweProbeClusterCreated(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_probe_cluster());
  const rtclog::BweProbeCluster& pcc_event = event.probe_cluster();
  LoggedBweProbeClusterCreatedEvent res;
  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_id());
  res.id = pcc_event.id();
  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_bitrate_bps());
  res.bitrate_bps = pcc_event.bitrate_bps();
  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_min_packets());
  res.min_packets = pcc_event.min_packets();
  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_min_bytes());
  res.min_bytes = pcc_event.min_bytes();
  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeFailureEvent>
ParsedRtcEventLog::GetBweProbeFailure(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::BWE_PROBE_RESULT_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
  const rtclog::BweProbeResult& pr_event = event.probe_result();
  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
  RTC_PARSE_CHECK_OR_RETURN_NE(pr_event.result(),
                               rtclog::BweProbeResult::SUCCESS);

  LoggedBweProbeFailureEvent res;
  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_id());
  res.id = pr_event.id();
  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
  if (pr_event.result() ==
      rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL) {
    res.failure_reason = ProbeFailureReason::kInvalidSendReceiveInterval;
  } else if (pr_event.result() ==
             rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO) {
    res.failure_reason = ProbeFailureReason::kInvalidSendReceiveRatio;
  } else if (pr_event.result() == rtclog::BweProbeResult::TIMEOUT) {
    res.failure_reason = ProbeFailureReason::kTimeout;
  } else {
    RTC_NOTREACHED();
  }
  RTC_PARSE_CHECK_OR_RETURN(!pr_event.has_bitrate_bps());

  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeSuccessEvent>
ParsedRtcEventLog::GetBweProbeSuccess(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
                               rtclog::Event::BWE_PROBE_RESULT_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
  const rtclog::BweProbeResult& pr_event = event.probe_result();
  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
  RTC_PARSE_CHECK_OR_RETURN_EQ(pr_event.result(),
                               rtclog::BweProbeResult::SUCCESS);

  LoggedBweProbeSuccessEvent res;
  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_id());
  res.id = pr_event.id();
  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_bitrate_bps());
  res.bitrate_bps = pr_event.bitrate_bps();

  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedAlrStateEvent>
ParsedRtcEventLog::GetAlrState(const rtclog::Event& event) const {
  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::ALR_STATE_EVENT);
  RTC_PARSE_CHECK_OR_RETURN(event.has_alr_state());
  const rtclog::AlrState& alr_event = event.alr_state();
  LoggedAlrStateEvent res;
  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(alr_event.has_in_alr());
  res.in_alr = alr_event.in_alr();

  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairConfig>
ParsedRtcEventLog::GetIceCandidatePairConfig(
    const rtclog::Event& rtc_event) const {
  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(rtc_event.type(),
                               rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
  LoggedIceCandidatePairConfig res;
  const rtclog::IceCandidatePairConfig& config =
      rtc_event.ice_candidate_pair_config();
  RTC_CHECK(rtc_event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(rtc_event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(config.has_config_type());
  res.type = GetRuntimeIceCandidatePairConfigType(config.config_type());
  RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_id());
  res.candidate_pair_id = config.candidate_pair_id();
  RTC_PARSE_CHECK_OR_RETURN(config.has_local_candidate_type());
  res.local_candidate_type =
      GetRuntimeIceCandidateType(config.local_candidate_type());
  RTC_PARSE_CHECK_OR_RETURN(config.has_local_relay_protocol());
  res.local_relay_protocol =
      GetRuntimeIceCandidatePairProtocol(config.local_relay_protocol());
  RTC_PARSE_CHECK_OR_RETURN(config.has_local_network_type());
  res.local_network_type =
      GetRuntimeIceCandidateNetworkType(config.local_network_type());
  RTC_PARSE_CHECK_OR_RETURN(config.has_local_address_family());
  res.local_address_family =
      GetRuntimeIceCandidatePairAddressFamily(config.local_address_family());
  RTC_PARSE_CHECK_OR_RETURN(config.has_remote_candidate_type());
  res.remote_candidate_type =
      GetRuntimeIceCandidateType(config.remote_candidate_type());
  RTC_PARSE_CHECK_OR_RETURN(config.has_remote_address_family());
  res.remote_address_family =
      GetRuntimeIceCandidatePairAddressFamily(config.remote_address_family());
  RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_protocol());
  res.candidate_pair_protocol =
      GetRuntimeIceCandidatePairProtocol(config.candidate_pair_protocol());
  return res;
}

ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairEvent>
ParsedRtcEventLog::GetIceCandidatePairEvent(
    const rtclog::Event& rtc_event) const {
  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_type());
  RTC_PARSE_CHECK_OR_RETURN_EQ(rtc_event.type(),
                               rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
  LoggedIceCandidatePairEvent res;
  const rtclog::IceCandidatePairEvent& event =
      rtc_event.ice_candidate_pair_event();
  RTC_CHECK(rtc_event.has_timestamp_us());
  res.timestamp = Timestamp::Micros(rtc_event.timestamp_us());
  RTC_PARSE_CHECK_OR_RETURN(event.has_event_type());
  res.type = GetRuntimeIceCandidatePairEventType(event.event_type());
  RTC_PARSE_CHECK_OR_RETURN(event.has_candidate_pair_id());
  res.candidate_pair_id = event.candidate_pair_id();
  // transaction_id is not supported by rtclog::Event
  res.transaction_id = 0;
  return res;
}

// Returns the MediaType for registered SSRCs. Search from the end to use last
// registered types first.
ParsedRtcEventLog::MediaType ParsedRtcEventLog::GetMediaType(
    uint32_t ssrc,
    PacketDirection direction) const {
  if (direction == kIncomingPacket) {
    if (std::find(incoming_video_ssrcs_.begin(), incoming_video_ssrcs_.end(),
                  ssrc) != incoming_video_ssrcs_.end()) {
      return MediaType::VIDEO;
    }
    if (std::find(incoming_audio_ssrcs_.begin(), incoming_audio_ssrcs_.end(),
                  ssrc) != incoming_audio_ssrcs_.end()) {
      return MediaType::AUDIO;
    }
  } else {
    if (std::find(outgoing_video_ssrcs_.begin(), outgoing_video_ssrcs_.end(),
                  ssrc) != outgoing_video_ssrcs_.end()) {
      return MediaType::VIDEO;
    }
    if (std::find(outgoing_audio_ssrcs_.begin(), outgoing_audio_ssrcs_.end(),
                  ssrc) != outgoing_audio_ssrcs_.end()) {
      return MediaType::AUDIO;
    }
  }
  return MediaType::ANY;
}

std::vector<InferredRouteChangeEvent> ParsedRtcEventLog::GetRouteChanges()
    const {
  std::vector<InferredRouteChangeEvent> route_changes;
  for (auto& candidate : ice_candidate_pair_configs()) {
    if (candidate.type == IceCandidatePairConfigType::kSelected) {
      InferredRouteChangeEvent route;
      route.route_id = candidate.candidate_pair_id;
      route.log_time = Timestamp::Millis(candidate.log_time_ms());

      route.send_overhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead;
      if (candidate.remote_address_family ==
          IceCandidatePairAddressFamily::kIpv6)
        route.send_overhead += kIpv6Overhead - kIpv4Overhead;
      if (candidate.remote_candidate_type != IceCandidateType::kLocal)
        route.send_overhead += kStunOverhead;
      route.return_overhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead;
      if (candidate.remote_address_family ==
          IceCandidatePairAddressFamily::kIpv6)
        route.return_overhead += kIpv6Overhead - kIpv4Overhead;
      if (candidate.remote_candidate_type != IceCandidateType::kLocal)
        route.return_overhead += kStunOverhead;
      route_changes.push_back(route);
    }
  }
  return route_changes;
}

std::vector<LoggedPacketInfo> ParsedRtcEventLog::GetPacketInfos(
    PacketDirection direction) const {
  std::map<uint32_t, MediaStreamInfo> streams;
  if (direction == PacketDirection::kIncomingPacket) {
    AddRecvStreamInfos(&streams, audio_recv_configs(), LoggedMediaType::kAudio);
    AddRecvStreamInfos(&streams, video_recv_configs(), LoggedMediaType::kVideo);
  } else if (direction == PacketDirection::kOutgoingPacket) {
    AddSendStreamInfos(&streams, audio_send_configs(), LoggedMediaType::kAudio);
    AddSendStreamInfos(&streams, video_send_configs(), LoggedMediaType::kVideo);
  }

  std::vector<OverheadChangeEvent> overheads =
      GetOverheadChangingEvents(GetRouteChanges(), direction);
  auto overhead_iter = overheads.begin();
  std::vector<LoggedPacketInfo> packets;
  std::map<int64_t, size_t> indices;
  uint16_t current_overhead = kDefaultOverhead;
  Timestamp last_log_time = Timestamp::Zero();
  SequenceNumberUnwrapper seq_num_unwrapper;

  auto advance_time = [&](Timestamp new_log_time) {
    if (overhead_iter != overheads.end() &&
        new_log_time >= overhead_iter->timestamp) {
      current_overhead = overhead_iter->overhead;
      ++overhead_iter;
    }
    // If we have a large time delta, it can be caused by a gap in logging,
    // therefore we don't want to match up sequence numbers as we might have had
    // a wraparound.
    if (new_log_time - last_log_time > TimeDelta::Seconds(30)) {
      seq_num_unwrapper = SequenceNumberUnwrapper();
      indices.clear();
    }
    RTC_DCHECK(new_log_time >= last_log_time);
    last_log_time = new_log_time;
  };

  auto rtp_handler = [&](const LoggedRtpPacket& rtp) {
    advance_time(Timestamp::Millis(rtp.log_time_ms()));
    MediaStreamInfo* stream = &streams[rtp.header.ssrc];
    Timestamp capture_time = Timestamp::MinusInfinity();
    if (!stream->rtx) {
      // RTX copy the timestamp of the retransmitted packets. This means that
      // RTX streams don't have a unique clock offset and frequency, so
      // the RTP timstamps can't be unwrapped.

      // Add an offset to avoid |capture_ticks| to become negative in the case
      // of reordering.
      constexpr int64_t kStartingCaptureTimeTicks = 90 * 48 * 10000;
      int64_t capture_ticks =
          kStartingCaptureTimeTicks +
          stream->unwrap_capture_ticks.Unwrap(rtp.header.timestamp);
      // TODO(srte): Use logged sample rate when it is added to the format.
      capture_time = Timestamp::Seconds(
          capture_ticks /
          (stream->media_type == LoggedMediaType::kAudio ? 48000.0 : 90000.0));
    }
    LoggedPacketInfo logged(rtp, stream->media_type, stream->rtx, capture_time);
    logged.overhead = current_overhead;
    if (logged.has_transport_seq_no) {
      logged.log_feedback_time = Timestamp::PlusInfinity();
      int64_t unwrapped_seq_num =
          seq_num_unwrapper.Unwrap(logged.transport_seq_no);
      if (indices.find(unwrapped_seq_num) != indices.end()) {
        auto prev = packets[indices[unwrapped_seq_num]];
        RTC_LOG(LS_WARNING)
            << "Repeated sent packet sequence number: " << unwrapped_seq_num
            << " Packet time:" << prev.log_packet_time.seconds() << "s vs "
            << logged.log_packet_time.seconds()
            << "s at:" << rtp.log_time_ms() / 1000;
      }
      indices[unwrapped_seq_num] = packets.size();
    }
    packets.push_back(logged);
  };

  Timestamp feedback_base_time = Timestamp::MinusInfinity();
  absl::optional<int64_t> last_feedback_base_time_us;

  auto feedback_handler =
      [&](const LoggedRtcpPacketTransportFeedback& logged_rtcp) {
        auto log_feedback_time = Timestamp::Millis(logged_rtcp.log_time_ms());
        advance_time(log_feedback_time);
        const auto& feedback = logged_rtcp.transport_feedback;
        // Add timestamp deltas to a local time base selected on first packet
        // arrival. This won't be the true time base, but makes it easier to
        // manually inspect time stamps.
        if (!last_feedback_base_time_us) {
          feedback_base_time = log_feedback_time;
        } else {
          feedback_base_time += TimeDelta::Micros(
              feedback.GetBaseDeltaUs(*last_feedback_base_time_us));
        }
        last_feedback_base_time_us = feedback.GetBaseTimeUs();

        std::vector<LoggedPacketInfo*> packet_feedbacks;
        packet_feedbacks.reserve(feedback.GetAllPackets().size());
        Timestamp receive_timestamp = feedback_base_time;
        std::vector<int64_t> unknown_seq_nums;
        for (const auto& packet : feedback.GetAllPackets()) {
          int64_t unwrapped_seq_num =
              seq_num_unwrapper.Unwrap(packet.sequence_number());
          auto it = indices.find(unwrapped_seq_num);
          if (it == indices.end()) {
            unknown_seq_nums.push_back(unwrapped_seq_num);
            continue;
          }
          LoggedPacketInfo* sent = &packets[it->second];
          if (log_feedback_time - sent->log_packet_time >
              TimeDelta::Seconds(60)) {
            RTC_LOG(LS_WARNING)
                << "Received very late feedback, possibly due to wraparound.";
            continue;
          }
          if (packet.received()) {
            receive_timestamp += TimeDelta::Micros(packet.delta_us());
            if (sent->reported_recv_time.IsInfinite()) {
              sent->reported_recv_time =
                  Timestamp::Millis(receive_timestamp.ms());
              sent->log_feedback_time = log_feedback_time;
            }
          } else {
            if (sent->reported_recv_time.IsInfinite() &&
                sent->log_feedback_time.IsInfinite()) {
              sent->reported_recv_time = Timestamp::PlusInfinity();
              sent->log_feedback_time = log_feedback_time;
            }
          }
          packet_feedbacks.push_back(sent);
        }
        if (!unknown_seq_nums.empty()) {
          RTC_LOG(LS_WARNING)
              << "Received feedback for unknown packets: "
              << unknown_seq_nums.front() << " - " << unknown_seq_nums.back();
        }
        if (packet_feedbacks.empty())
          return;
        LoggedPacketInfo* last = packet_feedbacks.back();
        last->last_in_feedback = true;
        for (LoggedPacketInfo* fb : packet_feedbacks) {
          if (direction == PacketDirection::kOutgoingPacket) {
            fb->feedback_hold_duration =
                last->reported_recv_time - fb->reported_recv_time;
          } else {
            fb->feedback_hold_duration =
                log_feedback_time - fb->log_packet_time;
          }
        }
      };

  RtcEventProcessor process;
  for (const auto& rtp_packets : rtp_packets_by_ssrc(direction)) {
    process.AddEvents(rtp_packets.packet_view, rtp_handler);
  }
  if (direction == PacketDirection::kOutgoingPacket) {
    process.AddEvents(incoming_transport_feedback_, feedback_handler);
  } else {
    process.AddEvents(outgoing_transport_feedback_, feedback_handler);
  }
  process.ProcessEventsInOrder();
  return packets;
}

std::vector<LoggedIceCandidatePairConfig> ParsedRtcEventLog::GetIceCandidates()
    const {
  std::vector<LoggedIceCandidatePairConfig> candidates;
  std::set<uint32_t> added;
  for (auto& candidate : ice_candidate_pair_configs()) {
    if (added.find(candidate.candidate_pair_id) == added.end()) {
      candidates.push_back(candidate);
      added.insert(candidate.candidate_pair_id);
    }
  }
  return candidates;
}

std::vector<LoggedIceEvent> ParsedRtcEventLog::GetIceEvents() const {
  using CheckType = IceCandidatePairEventType;
  using ConfigType = IceCandidatePairConfigType;
  using Combined = LoggedIceEventType;
  std::map<CheckType, Combined> check_map(
      {{CheckType::kCheckSent, Combined::kCheckSent},
       {CheckType::kCheckReceived, Combined::kCheckReceived},
       {CheckType::kCheckResponseSent, Combined::kCheckResponseSent},
       {CheckType::kCheckResponseReceived, Combined::kCheckResponseReceived}});
  std::map<ConfigType, Combined> config_map(
      {{ConfigType::kAdded, Combined::kAdded},
       {ConfigType::kUpdated, Combined::kUpdated},
       {ConfigType::kDestroyed, Combined::kDestroyed},
       {ConfigType::kSelected, Combined::kSelected}});
  std::vector<LoggedIceEvent> log_events;
  auto handle_check = [&](const LoggedIceCandidatePairEvent& check) {
    log_events.push_back(LoggedIceEvent{check.candidate_pair_id,
                                        Timestamp::Millis(check.log_time_ms()),
                                        check_map[check.type]});
  };
  auto handle_config = [&](const LoggedIceCandidatePairConfig& conf) {
    log_events.push_back(LoggedIceEvent{conf.candidate_pair_id,
                                        Timestamp::Millis(conf.log_time_ms()),
                                        config_map[conf.type]});
  };
  RtcEventProcessor process;
  process.AddEvents(ice_candidate_pair_events(), handle_check);
  process.AddEvents(ice_candidate_pair_configs(), handle_config);
  process.ProcessEventsInOrder();
  return log_events;
}

const std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
    const ParsedRtcEventLog& parsed_log) {
  std::vector<MatchedSendArrivalTimes> rtp_rtcp_matched;
  for (auto& packet :
       parsed_log.GetPacketInfos(PacketDirection::kOutgoingPacket)) {
    if (packet.log_feedback_time.IsFinite()) {
      rtp_rtcp_matched.emplace_back(packet.log_feedback_time.ms(),
                                    packet.log_packet_time.ms(),
                                    packet.reported_recv_time.ms_or(
                                        MatchedSendArrivalTimes::kNotReceived),
                                    packet.size);
    }
  }
  return rtp_rtcp_matched;
}

// Helper functions for new format start here
ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedNewFormatEvent(
    const rtclog2::EventStream& stream) {
  RTC_DCHECK_EQ(stream.stream_size(), 0);  // No legacy format event.

  RTC_DCHECK_EQ(
      stream.incoming_rtp_packets_size() + stream.outgoing_rtp_packets_size() +
          stream.incoming_rtcp_packets_size() +
          stream.outgoing_rtcp_packets_size() +
          stream.audio_playout_events_size() + stream.begin_log_events_size() +
          stream.end_log_events_size() + stream.loss_based_bwe_updates_size() +
          stream.delay_based_bwe_updates_size() +
          stream.dtls_transport_state_events_size() +
          stream.dtls_writable_states_size() +
          stream.audio_network_adaptations_size() +
          stream.probe_clusters_size() + stream.probe_success_size() +
          stream.probe_failure_size() + stream.alr_states_size() +
          stream.route_changes_size() + stream.remote_estimates_size() +
          stream.ice_candidate_configs_size() +
          stream.ice_candidate_events_size() +
          stream.audio_recv_stream_configs_size() +
          stream.audio_send_stream_configs_size() +
          stream.video_recv_stream_configs_size() +
          stream.video_send_stream_configs_size() +
          stream.generic_packets_sent_size() +
          stream.generic_packets_received_size() +
          stream.generic_acks_received_size() +
          stream.frame_decoded_events_size(),
      1u);

  if (stream.incoming_rtp_packets_size() == 1) {
    return StoreIncomingRtpPackets(stream.incoming_rtp_packets(0));
  } else if (stream.outgoing_rtp_packets_size() == 1) {
    return StoreOutgoingRtpPackets(stream.outgoing_rtp_packets(0));
  } else if (stream.incoming_rtcp_packets_size() == 1) {
    return StoreIncomingRtcpPackets(stream.incoming_rtcp_packets(0));
  } else if (stream.outgoing_rtcp_packets_size() == 1) {
    return StoreOutgoingRtcpPackets(stream.outgoing_rtcp_packets(0));
  } else if (stream.audio_playout_events_size() == 1) {
    return StoreAudioPlayoutEvent(stream.audio_playout_events(0));
  } else if (stream.begin_log_events_size() == 1) {
    return StoreStartEvent(stream.begin_log_events(0));
  } else if (stream.end_log_events_size() == 1) {
    return StoreStopEvent(stream.end_log_events(0));
  } else if (stream.loss_based_bwe_updates_size() == 1) {
    return StoreBweLossBasedUpdate(stream.loss_based_bwe_updates(0));
  } else if (stream.delay_based_bwe_updates_size() == 1) {
    return StoreBweDelayBasedUpdate(stream.delay_based_bwe_updates(0));
  } else if (stream.dtls_transport_state_events_size() == 1) {
    return StoreDtlsTransportState(stream.dtls_transport_state_events(0));
  } else if (stream.dtls_writable_states_size() == 1) {
    return StoreDtlsWritableState(stream.dtls_writable_states(0));
  } else if (stream.audio_network_adaptations_size() == 1) {
    return StoreAudioNetworkAdaptationEvent(
        stream.audio_network_adaptations(0));
  } else if (stream.probe_clusters_size() == 1) {
    return StoreBweProbeClusterCreated(stream.probe_clusters(0));
  } else if (stream.probe_success_size() == 1) {
    return StoreBweProbeSuccessEvent(stream.probe_success(0));
  } else if (stream.probe_failure_size() == 1) {
    return StoreBweProbeFailureEvent(stream.probe_failure(0));
  } else if (stream.alr_states_size() == 1) {
    return StoreAlrStateEvent(stream.alr_states(0));
  } else if (stream.route_changes_size() == 1) {
    return StoreRouteChangeEvent(stream.route_changes(0));
  } else if (stream.remote_estimates_size() == 1) {
    return StoreRemoteEstimateEvent(stream.remote_estimates(0));
  } else if (stream.ice_candidate_configs_size() == 1) {
    return StoreIceCandidatePairConfig(stream.ice_candidate_configs(0));
  } else if (stream.ice_candidate_events_size() == 1) {
    return StoreIceCandidateEvent(stream.ice_candidate_events(0));
  } else if (stream.audio_recv_stream_configs_size() == 1) {
    return StoreAudioRecvConfig(stream.audio_recv_stream_configs(0));
  } else if (stream.audio_send_stream_configs_size() == 1) {
    return StoreAudioSendConfig(stream.audio_send_stream_configs(0));
  } else if (stream.video_recv_stream_configs_size() == 1) {
    return StoreVideoRecvConfig(stream.video_recv_stream_configs(0));
  } else if (stream.video_send_stream_configs_size() == 1) {
    return StoreVideoSendConfig(stream.video_send_stream_configs(0));
  } else if (stream.generic_packets_received_size() == 1) {
    return StoreGenericPacketReceivedEvent(stream.generic_packets_received(0));
  } else if (stream.generic_packets_sent_size() == 1) {
    return StoreGenericPacketSentEvent(stream.generic_packets_sent(0));
  } else if (stream.generic_acks_received_size() == 1) {
    return StoreGenericAckReceivedEvent(stream.generic_acks_received(0));
  } else if (stream.frame_decoded_events_size() == 1) {
    return StoreFrameDecodedEvents(stream.frame_decoded_events(0));
  } else {
    RTC_NOTREACHED();
    return ParseStatus::Success();
  }
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAlrStateEvent(
    const rtclog2::AlrState& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_in_alr());
  LoggedAlrStateEvent alr_event;
  alr_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
  alr_event.in_alr = proto.in_alr();

  alr_state_events_.push_back(alr_event);
  // TODO(terelius): Should we delta encode this event type?
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreRouteChangeEvent(
    const rtclog2::RouteChange& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_connected());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_overhead());
  LoggedRouteChangeEvent route_event;
  route_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
  route_event.connected = proto.connected();
  route_event.overhead = proto.overhead();

  route_change_events_.push_back(route_event);
  // TODO(terelius): Should we delta encode this event type?
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreRemoteEstimateEvent(
    const rtclog2::RemoteEstimates& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  // Base event
  LoggedRemoteEstimateEvent base_event;
  base_event.timestamp = Timestamp::Millis(proto.timestamp_ms());

  absl::optional<uint64_t> base_link_capacity_lower_kbps;
  if (proto.has_link_capacity_lower_kbps()) {
    base_link_capacity_lower_kbps = proto.link_capacity_lower_kbps();
    base_event.link_capacity_lower =
        DataRate::KilobitsPerSec(proto.link_capacity_lower_kbps());
  }

  absl::optional<uint64_t> base_link_capacity_upper_kbps;
  if (proto.has_link_capacity_upper_kbps()) {
    base_link_capacity_upper_kbps = proto.link_capacity_upper_kbps();
    base_event.link_capacity_upper =
        DataRate::KilobitsPerSec(proto.link_capacity_upper_kbps());
  }

  remote_estimate_events_.push_back(base_event);

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  auto timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // link_capacity_lower_kbps
  auto link_capacity_lower_kbps_values =
      DecodeDeltas(proto.link_capacity_lower_kbps_deltas(),
                   base_link_capacity_lower_kbps, number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(link_capacity_lower_kbps_values.size(),
                               number_of_deltas);

  // link_capacity_upper_kbps
  auto link_capacity_upper_kbps_values =
      DecodeDeltas(proto.link_capacity_upper_kbps_deltas(),
                   base_link_capacity_upper_kbps, number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(link_capacity_upper_kbps_values.size(),
                               number_of_deltas);

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    LoggedRemoteEstimateEvent event;
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    event.timestamp = Timestamp::Millis(*timestamp_ms_values[i]);
    if (link_capacity_lower_kbps_values[i])
      event.link_capacity_lower =
          DataRate::KilobitsPerSec(*link_capacity_lower_kbps_values[i]);
    if (link_capacity_upper_kbps_values[i])
      event.link_capacity_upper =
          DataRate::KilobitsPerSec(*link_capacity_upper_kbps_values[i]);
    remote_estimate_events_.push_back(event);
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioPlayoutEvent(
    const rtclog2::AudioPlayoutEvents& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());

  // Base event
  audio_playout_events_[proto.local_ssrc()].emplace_back(
      Timestamp::Millis(proto.timestamp_ms()), proto.local_ssrc());

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // local_ssrc
  std::vector<absl::optional<uint64_t>> local_ssrc_values = DecodeDeltas(
      proto.local_ssrc_deltas(), proto.local_ssrc(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(local_ssrc_values.size(), number_of_deltas);

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(local_ssrc_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN_LE(local_ssrc_values[i].value(),
                                 std::numeric_limits<uint32_t>::max());

    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));

    const uint32_t local_ssrc =
        static_cast<uint32_t>(local_ssrc_values[i].value());
    audio_playout_events_[local_ssrc].emplace_back(
        Timestamp::Millis(timestamp_ms), local_ssrc);
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIncomingRtpPackets(
    const rtclog2::IncomingRtpPackets& proto) {
  return StoreRtpPackets(proto, &incoming_rtp_packets_map_);
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreOutgoingRtpPackets(
    const rtclog2::OutgoingRtpPackets& proto) {
  return StoreRtpPackets(proto, &outgoing_rtp_packets_map_);
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIncomingRtcpPackets(
    const rtclog2::IncomingRtcpPackets& proto) {
  return StoreRtcpPackets(proto, &incoming_rtcp_packets_,
                          /*remove_duplicates=*/true);
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreOutgoingRtcpPackets(
    const rtclog2::OutgoingRtcpPackets& proto) {
  return StoreRtcpPackets(proto, &outgoing_rtcp_packets_,
                          /*remove_duplicates=*/false);
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreStartEvent(
    const rtclog2::BeginLogEvent& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_version());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_utc_time_ms());
  RTC_PARSE_CHECK_OR_RETURN_EQ(proto.version(), 2);
  LoggedStartEvent start_event(Timestamp::Millis(proto.timestamp_ms()),
                               Timestamp::Millis(proto.utc_time_ms()));

  start_log_events_.push_back(start_event);
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreStopEvent(
    const rtclog2::EndLogEvent& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  LoggedStopEvent stop_event(Timestamp::Millis(proto.timestamp_ms()));

  stop_log_events_.push_back(stop_event);
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweLossBasedUpdate(
    const rtclog2::LossBasedBweUpdates& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_fraction_loss());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_total_packets());

  // Base event
  bwe_loss_updates_.emplace_back(Timestamp::Millis(proto.timestamp_ms()),
                                 proto.bitrate_bps(), proto.fraction_loss(),
                                 proto.total_packets());

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // bitrate_bps
  std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
      proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);

  // fraction_loss
  std::vector<absl::optional<uint64_t>> fraction_loss_values = DecodeDeltas(
      proto.fraction_loss_deltas(), proto.fraction_loss(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(fraction_loss_values.size(), number_of_deltas);

  // total_packets
  std::vector<absl::optional<uint64_t>> total_packets_values = DecodeDeltas(
      proto.total_packets_deltas(), proto.total_packets(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(total_packets_values.size(), number_of_deltas);

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));

    RTC_PARSE_CHECK_OR_RETURN(bitrate_bps_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN_LE(bitrate_bps_values[i].value(),
                                 std::numeric_limits<uint32_t>::max());
    const uint32_t bitrate_bps =
        static_cast<uint32_t>(bitrate_bps_values[i].value());

    RTC_PARSE_CHECK_OR_RETURN(fraction_loss_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN_LE(fraction_loss_values[i].value(),
                                 std::numeric_limits<uint32_t>::max());
    const uint32_t fraction_loss =
        static_cast<uint32_t>(fraction_loss_values[i].value());

    RTC_PARSE_CHECK_OR_RETURN(total_packets_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN_LE(total_packets_values[i].value(),
                                 std::numeric_limits<uint32_t>::max());
    const uint32_t total_packets =
        static_cast<uint32_t>(total_packets_values[i].value());

    bwe_loss_updates_.emplace_back(Timestamp::Millis(timestamp_ms), bitrate_bps,
                                   fraction_loss, total_packets);
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweDelayBasedUpdate(
    const rtclog2::DelayBasedBweUpdates& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_detector_state());

  // Base event
  const BandwidthUsage base_detector_state =
      GetRuntimeDetectorState(proto.detector_state());
  bwe_delay_updates_.emplace_back(Timestamp::Millis(proto.timestamp_ms()),
                                  proto.bitrate_bps(), base_detector_state);

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // bitrate_bps
  std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
      proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);

  // detector_state
  std::vector<absl::optional<uint64_t>> detector_state_values = DecodeDeltas(
      proto.detector_state_deltas(),
      static_cast<uint64_t>(proto.detector_state()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(detector_state_values.size(), number_of_deltas);

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));

    RTC_PARSE_CHECK_OR_RETURN(bitrate_bps_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN_LE(bitrate_bps_values[i].value(),
                                 std::numeric_limits<uint32_t>::max());
    const uint32_t bitrate_bps =
        static_cast<uint32_t>(bitrate_bps_values[i].value());

    RTC_PARSE_CHECK_OR_RETURN(detector_state_values[i].has_value());
    const auto detector_state =
        static_cast<rtclog2::DelayBasedBweUpdates::DetectorState>(
            detector_state_values[i].value());

    bwe_delay_updates_.emplace_back(Timestamp::Millis(timestamp_ms),
                                    bitrate_bps,
                                    GetRuntimeDetectorState(detector_state));
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeClusterCreated(
    const rtclog2::BweProbeCluster& proto) {
  LoggedBweProbeClusterCreatedEvent probe_cluster;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  probe_cluster.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
  probe_cluster.id = proto.id();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
  probe_cluster.bitrate_bps = proto.bitrate_bps();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_min_packets());
  probe_cluster.min_packets = proto.min_packets();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_min_bytes());
  probe_cluster.min_bytes = proto.min_bytes();

  bwe_probe_cluster_created_events_.push_back(probe_cluster);

  // TODO(terelius): Should we delta encode this event type?
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeSuccessEvent(
    const rtclog2::BweProbeResultSuccess& proto) {
  LoggedBweProbeSuccessEvent probe_result;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  probe_result.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
  probe_result.id = proto.id();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
  probe_result.bitrate_bps = proto.bitrate_bps();

  bwe_probe_success_events_.push_back(probe_result);

  // TODO(terelius): Should we delta encode this event type?
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeFailureEvent(
    const rtclog2::BweProbeResultFailure& proto) {
  LoggedBweProbeFailureEvent probe_result;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  probe_result.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
  probe_result.id = proto.id();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_failure());
  probe_result.failure_reason = GetRuntimeProbeFailureReason(proto.failure());

  bwe_probe_failure_events_.push_back(probe_result);

  // TODO(terelius): Should we delta encode this event type?
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreFrameDecodedEvents(
    const rtclog2::FrameDecodedEvents& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_render_time_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_width());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_height());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_codec());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_qp());

  LoggedFrameDecoded base_frame;
  base_frame.timestamp = Timestamp::Millis(proto.timestamp_ms());
  base_frame.ssrc = proto.ssrc();
  base_frame.render_time_ms = proto.render_time_ms();
  base_frame.width = proto.width();
  base_frame.height = proto.height();
  base_frame.codec = GetRuntimeCodecType(proto.codec());
  RTC_PARSE_CHECK_OR_RETURN_GE(proto.qp(), 0);
  RTC_PARSE_CHECK_OR_RETURN_LE(proto.qp(), 255);
  base_frame.qp = static_cast<uint8_t>(proto.qp());

  decoded_frames_[base_frame.ssrc].push_back(base_frame);

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // SSRC
  std::vector<absl::optional<uint64_t>> ssrc_values =
      DecodeDeltas(proto.ssrc_deltas(), proto.ssrc(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(ssrc_values.size(), number_of_deltas);

  // render_time_ms
  std::vector<absl::optional<uint64_t>> render_time_ms_values =
      DecodeDeltas(proto.render_time_ms_deltas(),
                   ToUnsigned(proto.render_time_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(render_time_ms_values.size(), number_of_deltas);

  // width
  std::vector<absl::optional<uint64_t>> width_values = DecodeDeltas(
      proto.width_deltas(), ToUnsigned(proto.width()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(width_values.size(), number_of_deltas);

  // height
  std::vector<absl::optional<uint64_t>> height_values = DecodeDeltas(
      proto.height_deltas(), ToUnsigned(proto.height()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(height_values.size(), number_of_deltas);

  // codec
  std::vector<absl::optional<uint64_t>> codec_values =
      DecodeDeltas(proto.codec_deltas(), static_cast<uint64_t>(proto.codec()),
                   number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(codec_values.size(), number_of_deltas);

  // qp
  std::vector<absl::optional<uint64_t>> qp_values =
      DecodeDeltas(proto.qp_deltas(), proto.qp(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(qp_values.size(), number_of_deltas);

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    LoggedFrameDecoded frame;
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
    frame.timestamp = Timestamp::Millis(timestamp_ms);

    RTC_PARSE_CHECK_OR_RETURN(ssrc_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN_LE(ssrc_values[i].value(),
                                 std::numeric_limits<uint32_t>::max());
    frame.ssrc = static_cast<uint32_t>(ssrc_values[i].value());

    RTC_PARSE_CHECK_OR_RETURN(render_time_ms_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(render_time_ms_values[i].value(), &frame.render_time_ms));

    RTC_PARSE_CHECK_OR_RETURN(width_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(ToSigned(width_values[i].value(), &frame.width));

    RTC_PARSE_CHECK_OR_RETURN(height_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(height_values[i].value(), &frame.height));

    RTC_PARSE_CHECK_OR_RETURN(codec_values[i].has_value());
    frame.codec =
        GetRuntimeCodecType(static_cast<rtclog2::FrameDecodedEvents::Codec>(
            codec_values[i].value()));

    RTC_PARSE_CHECK_OR_RETURN(qp_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN_LE(qp_values[i].value(),
                                 std::numeric_limits<uint8_t>::max());
    frame.qp = static_cast<uint8_t>(qp_values[i].value());

    decoded_frames_[frame.ssrc].push_back(frame);
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreGenericAckReceivedEvent(
    const rtclog2::GenericAckReceived& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_acked_packet_number());
  // receive_acked_packet_time_ms is optional.

  absl::optional<int64_t> base_receive_acked_packet_time_ms;
  if (proto.has_receive_acked_packet_time_ms()) {
    base_receive_acked_packet_time_ms = proto.receive_acked_packet_time_ms();
  }
  generic_acks_received_.push_back(
      {Timestamp::Millis(proto.timestamp_ms()), proto.packet_number(),
       proto.acked_packet_number(), base_receive_acked_packet_time_ms});

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // packet_number
  std::vector<absl::optional<uint64_t>> packet_number_values =
      DecodeDeltas(proto.packet_number_deltas(),
                   ToUnsigned(proto.packet_number()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);

  // acked_packet_number
  std::vector<absl::optional<uint64_t>> acked_packet_number_values =
      DecodeDeltas(proto.acked_packet_number_deltas(),
                   ToUnsigned(proto.acked_packet_number()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(acked_packet_number_values.size(),
                               number_of_deltas);

  // optional receive_acked_packet_time_ms
  const absl::optional<uint64_t> unsigned_receive_acked_packet_time_ms_base =
      proto.has_receive_acked_packet_time_ms()
          ? absl::optional<uint64_t>(
                ToUnsigned(proto.receive_acked_packet_time_ms()))
          : absl::optional<uint64_t>();
  std::vector<absl::optional<uint64_t>> receive_acked_packet_time_ms_values =
      DecodeDeltas(proto.receive_acked_packet_time_ms_deltas(),
                   unsigned_receive_acked_packet_time_ms_base,
                   number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(receive_acked_packet_time_ms_values.size(),
                               number_of_deltas);

  for (size_t i = 0; i < number_of_deltas; i++) {
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
    int64_t packet_number;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(packet_number_values[i].value(), &packet_number));
    int64_t acked_packet_number;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(acked_packet_number_values[i].value(), &acked_packet_number));
    absl::optional<int64_t> receive_acked_packet_time_ms;

    if (receive_acked_packet_time_ms_values[i].has_value()) {
      int64_t value;
      RTC_PARSE_CHECK_OR_RETURN(
          ToSigned(receive_acked_packet_time_ms_values[i].value(), &value));
      receive_acked_packet_time_ms = value;
    }
    generic_acks_received_.push_back({Timestamp::Millis(timestamp_ms),
                                      packet_number, acked_packet_number,
                                      receive_acked_packet_time_ms});
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreGenericPacketSentEvent(
    const rtclog2::GenericPacketSent& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());

  // Base event
  RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_overhead_length());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_payload_length());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_padding_length());

  generic_packets_sent_.push_back(
      {Timestamp::Millis(proto.timestamp_ms()), proto.packet_number(),
       static_cast<size_t>(proto.overhead_length()),
       static_cast<size_t>(proto.payload_length()),
       static_cast<size_t>(proto.padding_length())});

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // packet_number
  std::vector<absl::optional<uint64_t>> packet_number_values =
      DecodeDeltas(proto.packet_number_deltas(),
                   ToUnsigned(proto.packet_number()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);

  std::vector<absl::optional<uint64_t>> overhead_length_values =
      DecodeDeltas(proto.overhead_length_deltas(), proto.overhead_length(),
                   number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(overhead_length_values.size(), number_of_deltas);

  std::vector<absl::optional<uint64_t>> payload_length_values = DecodeDeltas(
      proto.payload_length_deltas(), proto.payload_length(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(payload_length_values.size(), number_of_deltas);

  std::vector<absl::optional<uint64_t>> padding_length_values = DecodeDeltas(
      proto.padding_length_deltas(), proto.padding_length(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(padding_length_values.size(), number_of_deltas);

  for (size_t i = 0; i < number_of_deltas; i++) {
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
    int64_t packet_number;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(packet_number_values[i].value(), &packet_number));
    RTC_PARSE_CHECK_OR_RETURN(overhead_length_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(payload_length_values[i].has_value());
    RTC_PARSE_CHECK_OR_RETURN(padding_length_values[i].has_value());
    generic_packets_sent_.push_back(
        {Timestamp::Millis(timestamp_ms), packet_number,
         static_cast<size_t>(overhead_length_values[i].value()),
         static_cast<size_t>(payload_length_values[i].value()),
         static_cast<size_t>(padding_length_values[i].value())});
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus
ParsedRtcEventLog::StoreGenericPacketReceivedEvent(
    const rtclog2::GenericPacketReceived& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());

  // Base event
  RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_length());

  generic_packets_received_.push_back({Timestamp::Millis(proto.timestamp_ms()),
                                       proto.packet_number(),
                                       proto.packet_length()});

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // packet_number
  std::vector<absl::optional<uint64_t>> packet_number_values =
      DecodeDeltas(proto.packet_number_deltas(),
                   ToUnsigned(proto.packet_number()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);

  std::vector<absl::optional<uint64_t>> packet_length_values = DecodeDeltas(
      proto.packet_length_deltas(), proto.packet_length(), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(packet_length_values.size(), number_of_deltas);

  for (size_t i = 0; i < number_of_deltas; i++) {
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
    int64_t packet_number;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(packet_number_values[i].value(), &packet_number));
    RTC_PARSE_CHECK_OR_RETURN_LE(packet_length_values[i].value(),
                                 std::numeric_limits<int32_t>::max());
    int32_t packet_length =
        static_cast<int32_t>(packet_length_values[i].value());
    generic_packets_received_.push_back(
        {Timestamp::Millis(timestamp_ms), packet_number, packet_length});
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus
ParsedRtcEventLog::StoreAudioNetworkAdaptationEvent(
    const rtclog2::AudioNetworkAdaptations& proto) {
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());

  // Base event
  {
    AudioEncoderRuntimeConfig runtime_config;
    if (proto.has_bitrate_bps()) {
      runtime_config.bitrate_bps = proto.bitrate_bps();
    }
    if (proto.has_frame_length_ms()) {
      runtime_config.frame_length_ms = proto.frame_length_ms();
    }
    if (proto.has_uplink_packet_loss_fraction()) {
      float uplink_packet_loss_fraction;
      RTC_PARSE_CHECK_OR_RETURN(ParsePacketLossFractionFromProtoFormat(
          proto.uplink_packet_loss_fraction(), &uplink_packet_loss_fraction));
      runtime_config.uplink_packet_loss_fraction = uplink_packet_loss_fraction;
    }
    if (proto.has_enable_fec()) {
      runtime_config.enable_fec = proto.enable_fec();
    }
    if (proto.has_enable_dtx()) {
      runtime_config.enable_dtx = proto.enable_dtx();
    }
    if (proto.has_num_channels()) {
      // Note: Encoding N as N-1 only done for |num_channels_deltas|.
      runtime_config.num_channels = proto.num_channels();
    }
    audio_network_adaptation_events_.emplace_back(
        Timestamp::Millis(proto.timestamp_ms()), runtime_config);
  }

  const size_t number_of_deltas =
      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
  if (number_of_deltas == 0) {
    return ParseStatus::Success();
  }

  // timestamp_ms
  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
      DecodeDeltas(proto.timestamp_ms_deltas(),
                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);

  // bitrate_bps
  const absl::optional<uint64_t> unsigned_base_bitrate_bps =
      proto.has_bitrate_bps()
          ? absl::optional<uint64_t>(ToUnsigned(proto.bitrate_bps()))
          : absl::optional<uint64_t>();
  std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
      proto.bitrate_bps_deltas(), unsigned_base_bitrate_bps, number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);

  // frame_length_ms
  const absl::optional<uint64_t> unsigned_base_frame_length_ms =
      proto.has_frame_length_ms()
          ? absl::optional<uint64_t>(ToUnsigned(proto.frame_length_ms()))
          : absl::optional<uint64_t>();
  std::vector<absl::optional<uint64_t>> frame_length_ms_values =
      DecodeDeltas(proto.frame_length_ms_deltas(),
                   unsigned_base_frame_length_ms, number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(frame_length_ms_values.size(), number_of_deltas);

  // uplink_packet_loss_fraction
  const absl::optional<uint64_t> uplink_packet_loss_fraction =
      proto.has_uplink_packet_loss_fraction()
          ? absl::optional<uint64_t>(proto.uplink_packet_loss_fraction())
          : absl::optional<uint64_t>();
  std::vector<absl::optional<uint64_t>> uplink_packet_loss_fraction_values =
      DecodeDeltas(proto.uplink_packet_loss_fraction_deltas(),
                   uplink_packet_loss_fraction, number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(uplink_packet_loss_fraction_values.size(),
                               number_of_deltas);

  // enable_fec
  const absl::optional<uint64_t> enable_fec =
      proto.has_enable_fec() ? absl::optional<uint64_t>(proto.enable_fec())
                             : absl::optional<uint64_t>();
  std::vector<absl::optional<uint64_t>> enable_fec_values =
      DecodeDeltas(proto.enable_fec_deltas(), enable_fec, number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(enable_fec_values.size(), number_of_deltas);

  // enable_dtx
  const absl::optional<uint64_t> enable_dtx =
      proto.has_enable_dtx() ? absl::optional<uint64_t>(proto.enable_dtx())
                             : absl::optional<uint64_t>();
  std::vector<absl::optional<uint64_t>> enable_dtx_values =
      DecodeDeltas(proto.enable_dtx_deltas(), enable_dtx, number_of_deltas);
  RTC_PARSE_CHECK_OR_RETURN_EQ(enable_dtx_values.size(), number_of_deltas);

  // num_channels
  // Note: For delta encoding, all num_channel values, including the base,
  // were shifted down by one, but in the base event, they were not.
  // We likewise shift the base event down by one, to get the same base as
  // encoding had, but then shift all of the values (except the base) back up
  // to their original value.
  absl::optional<uint64_t> shifted_base_num_channels;
  if (proto.has_num_channels()) {
    shifted_base_num_channels =
        absl::optional<uint64_t>(proto.num_channels() - 1);
  }
  std::vector<absl::optional<uint64_t>> num_channels_values = DecodeDeltas(
      proto.num_channels_deltas(), shifted_base_num_channels, number_of_deltas);
  for (size_t i = 0; i < num_channels_values.size(); ++i) {
    if (num_channels_values[i].has_value()) {
      num_channels_values[i] = num_channels_values[i].value() + 1;
    }
  }
  RTC_PARSE_CHECK_OR_RETURN_EQ(num_channels_values.size(), number_of_deltas);

  // Populate events from decoded deltas
  for (size_t i = 0; i < number_of_deltas; ++i) {
    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    int64_t timestamp_ms;
    RTC_PARSE_CHECK_OR_RETURN(
        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));

    AudioEncoderRuntimeConfig runtime_config;
    if (bitrate_bps_values[i].has_value()) {
      int signed_bitrate_bps;
      RTC_PARSE_CHECK_OR_RETURN(
          ToSigned(bitrate_bps_values[i].value(), &signed_bitrate_bps));
      runtime_config.bitrate_bps = signed_bitrate_bps;
    }
    if (frame_length_ms_values[i].has_value()) {
      int signed_frame_length_ms;
      RTC_PARSE_CHECK_OR_RETURN(
          ToSigned(frame_length_ms_values[i].value(), &signed_frame_length_ms));
      runtime_config.frame_length_ms = signed_frame_length_ms;
    }
    if (uplink_packet_loss_fraction_values[i].has_value()) {
      float uplink_packet_loss_fraction;
      RTC_PARSE_CHECK_OR_RETURN(ParsePacketLossFractionFromProtoFormat(
          rtc::checked_cast<uint32_t>(
              uplink_packet_loss_fraction_values[i].value()),
          &uplink_packet_loss_fraction));
      runtime_config.uplink_packet_loss_fraction = uplink_packet_loss_fraction;
    }
    if (enable_fec_values[i].has_value()) {
      runtime_config.enable_fec =
          rtc::checked_cast<bool>(enable_fec_values[i].value());
    }
    if (enable_dtx_values[i].has_value()) {
      runtime_config.enable_dtx =
          rtc::checked_cast<bool>(enable_dtx_values[i].value());
    }
    if (num_channels_values[i].has_value()) {
      runtime_config.num_channels =
          rtc::checked_cast<size_t>(num_channels_values[i].value());
    }
    audio_network_adaptation_events_.emplace_back(
        Timestamp::Millis(timestamp_ms), runtime_config);
  }
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreDtlsTransportState(
    const rtclog2::DtlsTransportStateEvent& proto) {
  LoggedDtlsTransportState dtls_state;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  dtls_state.timestamp = Timestamp::Millis(proto.timestamp_ms());

  RTC_PARSE_CHECK_OR_RETURN(proto.has_dtls_transport_state());
  dtls_state.dtls_transport_state =
      GetRuntimeDtlsTransportState(proto.dtls_transport_state());

  dtls_transport_states_.push_back(dtls_state);
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreDtlsWritableState(
    const rtclog2::DtlsWritableState& proto) {
  LoggedDtlsWritableState dtls_writable_state;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  dtls_writable_state.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_writable());
  dtls_writable_state.writable = proto.writable();

  dtls_writable_states_.push_back(dtls_writable_state);
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidatePairConfig(
    const rtclog2::IceCandidatePairConfig& proto) {
  LoggedIceCandidatePairConfig ice_config;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  ice_config.timestamp = Timestamp::Millis(proto.timestamp_ms());

  RTC_PARSE_CHECK_OR_RETURN(proto.has_config_type());
  ice_config.type = GetRuntimeIceCandidatePairConfigType(proto.config_type());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id());
  ice_config.candidate_pair_id = proto.candidate_pair_id();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_candidate_type());
  ice_config.local_candidate_type =
      GetRuntimeIceCandidateType(proto.local_candidate_type());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_relay_protocol());
  ice_config.local_relay_protocol =
      GetRuntimeIceCandidatePairProtocol(proto.local_relay_protocol());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_network_type());
  ice_config.local_network_type =
      GetRuntimeIceCandidateNetworkType(proto.local_network_type());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_address_family());
  ice_config.local_address_family =
      GetRuntimeIceCandidatePairAddressFamily(proto.local_address_family());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_candidate_type());
  ice_config.remote_candidate_type =
      GetRuntimeIceCandidateType(proto.remote_candidate_type());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_address_family());
  ice_config.remote_address_family =
      GetRuntimeIceCandidatePairAddressFamily(proto.remote_address_family());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_protocol());
  ice_config.candidate_pair_protocol =
      GetRuntimeIceCandidatePairProtocol(proto.candidate_pair_protocol());

  ice_candidate_pair_configs_.push_back(ice_config);

  // TODO(terelius): Should we delta encode this event type?
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidateEvent(
    const rtclog2::IceCandidatePairEvent& proto) {
  LoggedIceCandidatePairEvent ice_event;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  ice_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_event_type());
  ice_event.type = GetRuntimeIceCandidatePairEventType(proto.event_type());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id());
  ice_event.candidate_pair_id = proto.candidate_pair_id();
  // TODO(zstein): Make the transaction_id field required once all old versions
  // of the log (which don't have the field) are obsolete.
  ice_event.transaction_id =
      proto.has_transaction_id() ? proto.transaction_id() : 0;

  ice_candidate_pair_events_.push_back(ice_event);

  // TODO(terelius): Should we delta encode this event type?
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreVideoRecvConfig(
    const rtclog2::VideoRecvStreamConfig& proto) {
  LoggedVideoRecvConfig stream;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
  stream.config.remote_ssrc = proto.remote_ssrc();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
  stream.config.local_ssrc = proto.local_ssrc();
  if (proto.has_rtx_ssrc()) {
    stream.config.rtx_ssrc = proto.rtx_ssrc();
  }
  if (proto.has_header_extensions()) {
    stream.config.rtp_extensions =
        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
  }
  video_recv_configs_.push_back(stream);
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreVideoSendConfig(
    const rtclog2::VideoSendStreamConfig& proto) {
  LoggedVideoSendConfig stream;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
  stream.config.local_ssrc = proto.ssrc();
  if (proto.has_rtx_ssrc()) {
    stream.config.rtx_ssrc = proto.rtx_ssrc();
  }
  if (proto.has_header_extensions()) {
    stream.config.rtp_extensions =
        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
  }
  video_send_configs_.push_back(stream);
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioRecvConfig(
    const rtclog2::AudioRecvStreamConfig& proto) {
  LoggedAudioRecvConfig stream;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
  stream.config.remote_ssrc = proto.remote_ssrc();
  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
  stream.config.local_ssrc = proto.local_ssrc();
  if (proto.has_header_extensions()) {
    stream.config.rtp_extensions =
        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
  }
  audio_recv_configs_.push_back(stream);
  return ParseStatus::Success();
}

ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioSendConfig(
    const rtclog2::AudioSendStreamConfig& proto) {
  LoggedAudioSendConfig stream;
  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
  stream.config.local_ssrc = proto.ssrc();
  if (proto.has_header_extensions()) {
    stream.config.rtp_extensions =
        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
  }
  audio_send_configs_.push_back(stream);
  return ParseStatus::Success();
}

}  // namespace webrtc
