/*
 *  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(
        proto.timestamp_ms() * 1000, 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(
        1000 * 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(proto.timestamp_ms() * 1000, 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(1000 * 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) {
  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_us = timestamp_us;
      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_us = timestamp_us;
      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_us = timestamp_us;
      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_us = timestamp_us;
      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_us = timestamp_us;
      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_us = timestamp_us;
      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_us = timestamp_us;
      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_us = timestamp_us;
        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_us = timestamp_us;
        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_us = timestamp_us;
      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 LoggedRtpPacketIncoming* ptr,
    size_t num_elements)
    : ssrc(ssrc),
      packet_view(PacketView<const LoggedRtpPacket>::Create(
          ptr,
          num_elements,
          offsetof(LoggedRtpPacketIncoming, rtp))) {}

ParsedRtcEventLog::LoggedRtpStreamView::LoggedRtpStreamView(
    uint32_t ssrc,
    const LoggedRtpPacketOutgoing* ptr,
    size_t num_elements)
    : ssrc(ssrc),
      packet_view(PacketView<const LoggedRtpPacket>::Create(
          ptr,
          num_elements,
          offsetof(LoggedRtpPacketOutgoing, 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.data(),
                            stream.incoming_packets.size()));
  }
  for (const auto& stream : outgoing_rtp_packets_by_ssrc_) {
    outgoing_rtp_packet_views_by_ssrc_.emplace_back(
        LoggedRtpStreamView(stream.ssrc, stream.outgoing_packets.data(),
                            stream.outgoing_packets.size()));
  }

  // 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 too large.";
      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
                                           kIncompleteLogError);
      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_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_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_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_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_us, parsed_header, header_length,
                                    total_length));
      } else {
        outgoing_rtp_packets_map_[parsed_header.ssrc].push_back(
            LoggedRtpPacketOutgoing(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_us, packet));
        last_incoming_rtcp_packet_ = packet;
      } else {
        outgoing_rtcp_packets_.push_back(
            LoggedRtcpPacketOutgoing(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_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_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_us = 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_us = 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_us = 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_us = 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_us = 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_us = 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_us = 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_us = 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_us = 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_us = 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_us = proto.timestamp_ms() * 1000;
  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_ms = 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_ms = 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_ms = *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(
      1000 * 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(1000 * 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(proto.timestamp_ms() * 1000,
                               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(proto.timestamp_ms() * 1000);

  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(1000 * 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(1000 * 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(1000 * 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(1000 * 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_us = proto.timestamp_ms() * 1000;
  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_us = proto.timestamp_ms() * 1000;
  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_us = proto.timestamp_ms() * 1000;
  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_us = 1000 * 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_us = 1000 * 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(
      {proto.timestamp_ms() * 1000, 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_ms * 1000, 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(
      {proto.timestamp_ms() * 1000, 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_ms * 1000, 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({proto.timestamp_ms() * 1000,
                                       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_ms * 1000, 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(1000 * 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(1000 * 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_us = proto.timestamp_ms() * 1000;

  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_us = proto.timestamp_ms() * 1000;
  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_us = proto.timestamp_ms() * 1000;

  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_us = proto.timestamp_ms() * 1000;
  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_us = proto.timestamp_ms() * 1000;
  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_us = proto.timestamp_ms() * 1000;
  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_us = proto.timestamp_ms() * 1000;
  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_us = proto.timestamp_ms() * 1000;
  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
