tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtc_event_log_parser.cc (164428B)


      1 /*
      2 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "logging/rtc_event_log/rtc_event_log_parser.h"
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 #include <cstring>
     16 #include <limits>
     17 #include <map>
     18 #include <optional>
     19 #include <set>
     20 #include <string>
     21 #include <tuple>
     22 #include <utility>
     23 #include <vector>
     24 
     25 #include "absl/strings/string_view.h"
     26 #include "api/candidate.h"
     27 #include "api/dtls_transport_interface.h"
     28 #include "api/rtc_event_log/rtc_event.h"
     29 #include "api/rtp_headers.h"
     30 #include "api/rtp_parameters.h"
     31 #include "api/transport/bandwidth_usage.h"
     32 #include "api/units/data_rate.h"
     33 #include "api/units/time_delta.h"
     34 #include "api/units/timestamp.h"
     35 #include "api/video/video_codec_type.h"
     36 #include "logging/rtc_event_log/dependency_descriptor_encoder_decoder.h"
     37 #include "logging/rtc_event_log/encoder/blob_encoding.h"
     38 #include "logging/rtc_event_log/encoder/delta_encoding.h"
     39 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
     40 #include "logging/rtc_event_log/encoder/var_int.h"
     41 #include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
     42 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
     43 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
     44 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
     45 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
     46 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
     47 #include "logging/rtc_event_log/events/rtc_event_begin_log.h"
     48 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
     49 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
     50 #include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
     51 #include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
     52 #include "logging/rtc_event_log/events/rtc_event_end_log.h"
     53 #include "logging/rtc_event_log/events/rtc_event_frame_decoded.h"
     54 #include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
     55 #include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
     56 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
     57 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
     58 #include "logging/rtc_event_log/events/rtc_event_log_parse_status.h"
     59 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
     60 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
     61 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
     62 #include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
     63 #include "logging/rtc_event_log/events/rtc_event_route_change.h"
     64 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
     65 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
     66 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
     67 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
     68 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
     69 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
     70 #include "logging/rtc_event_log/rtc_event_log.pb.h"
     71 #include "logging/rtc_event_log/rtc_event_log2.pb.h"
     72 #include "logging/rtc_event_log/rtc_event_processor.h"
     73 #include "logging/rtc_event_log/rtc_stream_config.h"
     74 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
     75 #include "modules/rtp_rtcp/include/rtp_cvo.h"
     76 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
     77 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     78 #include "modules/rtp_rtcp/source/ntp_time_util.h"
     79 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
     80 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
     81 #include "modules/rtp_rtcp/source/rtcp_packet/congestion_control_feedback.h"
     82 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
     83 #include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
     84 #include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
     85 #include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
     86 #include "modules/rtp_rtcp/source/rtcp_packet/psfb.h"
     87 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
     88 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
     89 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
     90 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
     91 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
     92 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     93 #include "rtc_base/checks.h"
     94 #include "rtc_base/copy_on_write_buffer.h"
     95 #include "rtc_base/logging.h"
     96 #include "rtc_base/numerics/safe_conversions.h"
     97 #include "rtc_base/numerics/sequence_number_unwrapper.h"
     98 #include "rtc_base/protobuf_utils.h"
     99 #include "rtc_base/system/file_wrapper.h"
    100 
    101 using webrtc_event_logging::ToSigned;
    102 using webrtc_event_logging::ToUnsigned;
    103 
    104 namespace webrtc {
    105 
    106 namespace {
    107 constexpr size_t kMaxLogSize = 250000000;
    108 
    109 constexpr size_t kIpv4Overhead = 20;
    110 constexpr size_t kIpv6Overhead = 40;
    111 constexpr size_t kUdpOverhead = 8;
    112 constexpr size_t kSrtpOverhead = 10;
    113 constexpr size_t kStunOverhead = 4;
    114 constexpr uint16_t kDefaultOverhead =
    115    kUdpOverhead + kSrtpOverhead + kIpv4Overhead;
    116 
    117 constexpr char kIncompleteLogError[] =
    118    "Could not parse the entire log. Only the beginning will be used.";
    119 
    120 struct MediaStreamInfo {
    121  MediaStreamInfo() = default;
    122  MediaStreamInfo(LoggedMediaType media_type, bool rtx)
    123      : media_type(media_type), rtx(rtx) {}
    124  LoggedMediaType media_type = LoggedMediaType::kUnknown;
    125  bool rtx = false;
    126  SeqNumUnwrapper<uint32_t> unwrap_capture_ticks;
    127 };
    128 
    129 template <typename Iterable>
    130 void AddRecvStreamInfos(std::map<uint32_t, MediaStreamInfo>* streams,
    131                        const Iterable configs,
    132                        LoggedMediaType media_type) {
    133  for (auto& conf : configs) {
    134    streams->insert({conf.config.remote_ssrc, {media_type, false}});
    135    if (conf.config.rtx_ssrc != 0)
    136      streams->insert({conf.config.rtx_ssrc, {media_type, true}});
    137  }
    138 }
    139 template <typename Iterable>
    140 void AddSendStreamInfos(std::map<uint32_t, MediaStreamInfo>* streams,
    141                        const Iterable configs,
    142                        LoggedMediaType media_type) {
    143  for (auto& conf : configs) {
    144    streams->insert({conf.config.local_ssrc, {media_type, false}});
    145    if (conf.config.rtx_ssrc != 0)
    146      streams->insert({conf.config.rtx_ssrc, {media_type, true}});
    147  }
    148 }
    149 struct OverheadChangeEvent {
    150  Timestamp timestamp;
    151  uint16_t overhead;
    152 };
    153 std::vector<OverheadChangeEvent> GetOverheadChangingEvents(
    154    const std::vector<InferredRouteChangeEvent>& route_changes,
    155    PacketDirection direction) {
    156  std::vector<OverheadChangeEvent> overheads;
    157  for (auto& event : route_changes) {
    158    uint16_t new_overhead = direction == PacketDirection::kIncomingPacket
    159                                ? event.return_overhead
    160                                : event.send_overhead;
    161    if (overheads.empty() || new_overhead != overheads.back().overhead) {
    162      overheads.push_back({event.log_time, new_overhead});
    163    }
    164  }
    165  return overheads;
    166 }
    167 
    168 bool IdenticalRtcpContents(const std::vector<uint8_t>& last_rtcp,
    169                           absl::string_view new_rtcp) {
    170  if (last_rtcp.size() != new_rtcp.size())
    171    return false;
    172  return memcmp(last_rtcp.data(), new_rtcp.data(), new_rtcp.size()) == 0;
    173 }
    174 
    175 // Conversion functions for legacy wire format.
    176 RtcpMode GetRuntimeRtcpMode(rtclog::VideoReceiveConfig::RtcpMode rtcp_mode) {
    177  switch (rtcp_mode) {
    178    case rtclog::VideoReceiveConfig::RTCP_COMPOUND:
    179      return RtcpMode::kCompound;
    180    case rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE:
    181      return RtcpMode::kReducedSize;
    182  }
    183  RTC_DCHECK_NOTREACHED();
    184  return RtcpMode::kOff;
    185 }
    186 
    187 BandwidthUsage GetRuntimeDetectorState(
    188    rtclog::DelayBasedBweUpdate::DetectorState detector_state) {
    189  switch (detector_state) {
    190    case rtclog::DelayBasedBweUpdate::BWE_NORMAL:
    191      return BandwidthUsage::kBwNormal;
    192    case rtclog::DelayBasedBweUpdate::BWE_UNDERUSING:
    193      return BandwidthUsage::kBwUnderusing;
    194    case rtclog::DelayBasedBweUpdate::BWE_OVERUSING:
    195      return BandwidthUsage::kBwOverusing;
    196  }
    197  RTC_DCHECK_NOTREACHED();
    198  return BandwidthUsage::kBwNormal;
    199 }
    200 
    201 IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType(
    202    rtclog::IceCandidatePairConfig::IceCandidatePairConfigType type) {
    203  switch (type) {
    204    case rtclog::IceCandidatePairConfig::ADDED:
    205      return IceCandidatePairConfigType::kAdded;
    206    case rtclog::IceCandidatePairConfig::UPDATED:
    207      return IceCandidatePairConfigType::kUpdated;
    208    case rtclog::IceCandidatePairConfig::DESTROYED:
    209      return IceCandidatePairConfigType::kDestroyed;
    210    case rtclog::IceCandidatePairConfig::SELECTED:
    211      return IceCandidatePairConfigType::kSelected;
    212  }
    213  RTC_DCHECK_NOTREACHED();
    214  return IceCandidatePairConfigType::kAdded;
    215 }
    216 
    217 // Converts a log type (proto based) to a matching `IceCandidateType` value
    218 // and checks for validity of the log type (since the enums aren't a perfect
    219 // match).
    220 bool GetRuntimeIceCandidateType(
    221    rtclog::IceCandidatePairConfig::IceCandidateType log_type,
    222    IceCandidateType& parsed_type) {
    223  switch (log_type) {
    224    case rtclog::IceCandidatePairConfig::LOCAL:
    225      parsed_type = IceCandidateType::kHost;
    226      break;
    227    case rtclog::IceCandidatePairConfig::STUN:
    228      parsed_type = IceCandidateType::kSrflx;
    229      break;
    230    case rtclog::IceCandidatePairConfig::PRFLX:
    231      parsed_type = IceCandidateType::kPrflx;
    232      break;
    233    case rtclog::IceCandidatePairConfig::RELAY:
    234      parsed_type = IceCandidateType::kRelay;
    235      break;
    236    default:
    237      return false;
    238  }
    239  return true;
    240 }
    241 
    242 IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
    243    rtclog::IceCandidatePairConfig::Protocol protocol) {
    244  switch (protocol) {
    245    case rtclog::IceCandidatePairConfig::UDP:
    246      return IceCandidatePairProtocol::kUdp;
    247    case rtclog::IceCandidatePairConfig::TCP:
    248      return IceCandidatePairProtocol::kTcp;
    249    case rtclog::IceCandidatePairConfig::SSLTCP:
    250      return IceCandidatePairProtocol::kSsltcp;
    251    case rtclog::IceCandidatePairConfig::TLS:
    252      return IceCandidatePairProtocol::kTls;
    253    case rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL:
    254      return IceCandidatePairProtocol::kUnknown;
    255  }
    256  RTC_DCHECK_NOTREACHED();
    257  return IceCandidatePairProtocol::kUnknown;
    258 }
    259 
    260 IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
    261    rtclog::IceCandidatePairConfig::AddressFamily address_family) {
    262  switch (address_family) {
    263    case rtclog::IceCandidatePairConfig::IPV4:
    264      return IceCandidatePairAddressFamily::kIpv4;
    265    case rtclog::IceCandidatePairConfig::IPV6:
    266      return IceCandidatePairAddressFamily::kIpv6;
    267    case rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY:
    268      return IceCandidatePairAddressFamily::kUnknown;
    269  }
    270  RTC_DCHECK_NOTREACHED();
    271  return IceCandidatePairAddressFamily::kUnknown;
    272 }
    273 
    274 IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
    275    rtclog::IceCandidatePairConfig::NetworkType network_type) {
    276  switch (network_type) {
    277    case rtclog::IceCandidatePairConfig::ETHERNET:
    278      return IceCandidateNetworkType::kEthernet;
    279    case rtclog::IceCandidatePairConfig::LOOPBACK:
    280      return IceCandidateNetworkType::kLoopback;
    281    case rtclog::IceCandidatePairConfig::WIFI:
    282      return IceCandidateNetworkType::kWifi;
    283    case rtclog::IceCandidatePairConfig::VPN:
    284      return IceCandidateNetworkType::kVpn;
    285    case rtclog::IceCandidatePairConfig::CELLULAR:
    286      return IceCandidateNetworkType::kCellular;
    287    case rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE:
    288      return IceCandidateNetworkType::kUnknown;
    289  }
    290  RTC_DCHECK_NOTREACHED();
    291  return IceCandidateNetworkType::kUnknown;
    292 }
    293 
    294 IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
    295    rtclog::IceCandidatePairEvent::IceCandidatePairEventType type) {
    296  switch (type) {
    297    case rtclog::IceCandidatePairEvent::CHECK_SENT:
    298      return IceCandidatePairEventType::kCheckSent;
    299    case rtclog::IceCandidatePairEvent::CHECK_RECEIVED:
    300      return IceCandidatePairEventType::kCheckReceived;
    301    case rtclog::IceCandidatePairEvent::CHECK_RESPONSE_SENT:
    302      return IceCandidatePairEventType::kCheckResponseSent;
    303    case rtclog::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED:
    304      return IceCandidatePairEventType::kCheckResponseReceived;
    305  }
    306  RTC_DCHECK_NOTREACHED();
    307  return IceCandidatePairEventType::kCheckSent;
    308 }
    309 
    310 VideoCodecType GetRuntimeCodecType(rtclog2::FrameDecodedEvents::Codec codec) {
    311  switch (codec) {
    312    case rtclog2::FrameDecodedEvents::CODEC_GENERIC:
    313      return VideoCodecType::kVideoCodecGeneric;
    314    case rtclog2::FrameDecodedEvents::CODEC_VP8:
    315      return VideoCodecType::kVideoCodecVP8;
    316    case rtclog2::FrameDecodedEvents::CODEC_VP9:
    317      return VideoCodecType::kVideoCodecVP9;
    318    case rtclog2::FrameDecodedEvents::CODEC_AV1:
    319      return VideoCodecType::kVideoCodecAV1;
    320    case rtclog2::FrameDecodedEvents::CODEC_H264:
    321      return VideoCodecType::kVideoCodecH264;
    322    case rtclog2::FrameDecodedEvents::CODEC_H265:
    323      return VideoCodecType::kVideoCodecH265;
    324    case rtclog2::FrameDecodedEvents::CODEC_UNKNOWN:
    325      RTC_LOG(LS_ERROR) << "Unknown codec type. Returning generic.";
    326      return VideoCodecType::kVideoCodecGeneric;
    327  }
    328  RTC_DCHECK_NOTREACHED();
    329  return VideoCodecType::kVideoCodecGeneric;
    330 }
    331 
    332 ParsedRtcEventLog::ParseStatus GetHeaderExtensions(
    333    std::vector<RtpExtension>* header_extensions,
    334    const RepeatedPtrField<rtclog::RtpHeaderExtension>&
    335        proto_header_extensions) {
    336  header_extensions->clear();
    337  for (auto& p : proto_header_extensions) {
    338    RTC_PARSE_CHECK_OR_RETURN(p.has_name());
    339    RTC_PARSE_CHECK_OR_RETURN(p.has_id());
    340    const std::string& name = p.name();
    341    int id = p.id();
    342    header_extensions->push_back(RtpExtension(name, id));
    343  }
    344  return ParsedRtcEventLog::ParseStatus::Success();
    345 }
    346 
    347 template <typename ProtoType, typename LoggedType>
    348 ParsedRtcEventLog::ParseStatus StoreRtpPackets(
    349    const ProtoType& proto,
    350    std::map<uint32_t, std::vector<LoggedType>>* rtp_packets_map) {
    351  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
    352  RTC_PARSE_CHECK_OR_RETURN(proto.has_marker());
    353  RTC_PARSE_CHECK_OR_RETURN(proto.has_payload_type());
    354  RTC_PARSE_CHECK_OR_RETURN(proto.has_sequence_number());
    355  RTC_PARSE_CHECK_OR_RETURN(proto.has_rtp_timestamp());
    356  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
    357  RTC_PARSE_CHECK_OR_RETURN(proto.has_payload_size());
    358  RTC_PARSE_CHECK_OR_RETURN(proto.has_header_size());
    359  RTC_PARSE_CHECK_OR_RETURN(proto.has_padding_size());
    360 
    361  const size_t number_of_deltas =
    362      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
    363  const size_t total_packets = number_of_deltas + 1;
    364 
    365  std::vector<std::vector<uint8_t>> dependency_descriptor_wire_format(
    366      total_packets);
    367  if (proto.has_dependency_descriptor()) {
    368    auto status_or_decoded =
    369        RtcEventLogDependencyDescriptorEncoderDecoder::Decode(
    370            proto.dependency_descriptor(), total_packets);
    371    if (!status_or_decoded.ok()) {
    372      return status_or_decoded.status();
    373    }
    374    dependency_descriptor_wire_format = status_or_decoded.value();
    375  }
    376 
    377  // Base event
    378  {
    379    RTPHeader header;
    380    RTC_PARSE_CHECK_OR_RETURN(
    381        IsValueInRangeForNumericType<bool>(proto.marker()));
    382    header.markerBit = static_cast<bool>(proto.marker());
    383    RTC_PARSE_CHECK_OR_RETURN(
    384        IsValueInRangeForNumericType<uint8_t>(proto.payload_type()));
    385    header.payloadType = static_cast<uint8_t>(proto.payload_type());
    386 
    387    RTC_PARSE_CHECK_OR_RETURN(
    388        IsValueInRangeForNumericType<uint16_t>(proto.sequence_number()));
    389    header.sequenceNumber = static_cast<uint16_t>(proto.sequence_number());
    390    RTC_PARSE_CHECK_OR_RETURN(
    391        IsValueInRangeForNumericType<uint32_t>(proto.rtp_timestamp()));
    392    header.timestamp = static_cast<uint32_t>(proto.rtp_timestamp());
    393    RTC_PARSE_CHECK_OR_RETURN(
    394        IsValueInRangeForNumericType<uint32_t>(proto.ssrc()));
    395    header.ssrc = static_cast<uint32_t>(proto.ssrc());
    396    header.numCSRCs = 0;  // TODO(terelius): Implement CSRC.
    397    RTC_PARSE_CHECK_OR_RETURN(
    398        IsValueInRangeForNumericType<size_t>(proto.padding_size()));
    399    header.paddingLength = static_cast<size_t>(proto.padding_size());
    400    RTC_PARSE_CHECK_OR_RETURN(
    401        IsValueInRangeForNumericType<size_t>(proto.header_size()));
    402    header.headerLength = static_cast<size_t>(proto.header_size());
    403    // TODO(terelius): Should we implement payload_type_frequency?
    404    if (proto.has_transport_sequence_number()) {
    405      header.extension.hasTransportSequenceNumber = true;
    406      RTC_PARSE_CHECK_OR_RETURN(IsValueInRangeForNumericType<uint16_t>(
    407          proto.transport_sequence_number()));
    408      header.extension.transportSequenceNumber =
    409          static_cast<uint16_t>(proto.transport_sequence_number());
    410    }
    411    if (proto.has_transmission_time_offset()) {
    412      header.extension.hasTransmissionTimeOffset = true;
    413      RTC_PARSE_CHECK_OR_RETURN(IsValueInRangeForNumericType<int32_t>(
    414          proto.transmission_time_offset()));
    415      header.extension.transmissionTimeOffset =
    416          static_cast<int32_t>(proto.transmission_time_offset());
    417    }
    418    if (proto.has_absolute_send_time()) {
    419      header.extension.hasAbsoluteSendTime = true;
    420      RTC_PARSE_CHECK_OR_RETURN(
    421          IsValueInRangeForNumericType<uint32_t>(proto.absolute_send_time()));
    422      header.extension.absoluteSendTime =
    423          static_cast<uint32_t>(proto.absolute_send_time());
    424    }
    425    if (proto.has_video_rotation()) {
    426      header.extension.hasVideoRotation = true;
    427      RTC_PARSE_CHECK_OR_RETURN(
    428          IsValueInRangeForNumericType<uint8_t>(proto.video_rotation()));
    429      header.extension.videoRotation = ConvertCVOByteToVideoRotation(
    430          static_cast<uint8_t>(proto.video_rotation()));
    431    }
    432    if (proto.has_audio_level()) {
    433      RTC_PARSE_CHECK_OR_RETURN(proto.has_voice_activity());
    434      RTC_PARSE_CHECK_OR_RETURN(
    435          IsValueInRangeForNumericType<bool>(proto.voice_activity()));
    436      bool voice_activity = static_cast<bool>(proto.voice_activity());
    437      RTC_PARSE_CHECK_OR_RETURN(
    438          IsValueInRangeForNumericType<int>(proto.audio_level()));
    439      int audio_level = static_cast<int>(proto.audio_level());
    440      RTC_PARSE_CHECK_OR_RETURN_LE(audio_level, 0x7F);
    441      header.extension.set_audio_level(AudioLevel(voice_activity, audio_level));
    442    } else {
    443      RTC_PARSE_CHECK_OR_RETURN(!proto.has_voice_activity());
    444    }
    445    LoggedType logged_packet(
    446        Timestamp::Millis(proto.timestamp_ms()), header, proto.header_size(),
    447        proto.payload_size() + header.headerLength + header.paddingLength);
    448    if (!dependency_descriptor_wire_format[0].empty()) {
    449      logged_packet.rtp.dependency_descriptor_wire_format =
    450          dependency_descriptor_wire_format[0];
    451    }
    452    (*rtp_packets_map)[header.ssrc].push_back(std::move(logged_packet));
    453  }
    454 
    455  if (number_of_deltas == 0) {
    456    return ParsedRtcEventLog::ParseStatus::Success();
    457  }
    458 
    459  // timestamp_ms (event)
    460  std::vector<std::optional<uint64_t>> timestamp_ms_values =
    461      DecodeDeltas(proto.timestamp_ms_deltas(),
    462                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
    463  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
    464 
    465  // marker (RTP base)
    466  std::vector<std::optional<uint64_t>> marker_values =
    467      DecodeDeltas(proto.marker_deltas(), proto.marker(), number_of_deltas);
    468  RTC_PARSE_CHECK_OR_RETURN_EQ(marker_values.size(), number_of_deltas);
    469 
    470  // payload_type (RTP base)
    471  std::vector<std::optional<uint64_t>> payload_type_values = DecodeDeltas(
    472      proto.payload_type_deltas(), proto.payload_type(), number_of_deltas);
    473  RTC_PARSE_CHECK_OR_RETURN_EQ(payload_type_values.size(), number_of_deltas);
    474 
    475  // sequence_number (RTP base)
    476  std::vector<std::optional<uint64_t>> sequence_number_values =
    477      DecodeDeltas(proto.sequence_number_deltas(), proto.sequence_number(),
    478                   number_of_deltas);
    479  RTC_PARSE_CHECK_OR_RETURN_EQ(sequence_number_values.size(), number_of_deltas);
    480 
    481  // rtp_timestamp (RTP base)
    482  std::vector<std::optional<uint64_t>> rtp_timestamp_values = DecodeDeltas(
    483      proto.rtp_timestamp_deltas(), proto.rtp_timestamp(), number_of_deltas);
    484  RTC_PARSE_CHECK_OR_RETURN_EQ(rtp_timestamp_values.size(), number_of_deltas);
    485 
    486  // ssrc (RTP base)
    487  std::vector<std::optional<uint64_t>> ssrc_values =
    488      DecodeDeltas(proto.ssrc_deltas(), proto.ssrc(), number_of_deltas);
    489  RTC_PARSE_CHECK_OR_RETURN_EQ(ssrc_values.size(), number_of_deltas);
    490 
    491  // payload_size (RTP base)
    492  std::vector<std::optional<uint64_t>> payload_size_values = DecodeDeltas(
    493      proto.payload_size_deltas(), proto.payload_size(), number_of_deltas);
    494  RTC_PARSE_CHECK_OR_RETURN_EQ(payload_size_values.size(), number_of_deltas);
    495 
    496  // header_size (RTP base)
    497  std::vector<std::optional<uint64_t>> header_size_values = DecodeDeltas(
    498      proto.header_size_deltas(), proto.header_size(), number_of_deltas);
    499  RTC_PARSE_CHECK_OR_RETURN_EQ(header_size_values.size(), number_of_deltas);
    500 
    501  // padding_size (RTP base)
    502  std::vector<std::optional<uint64_t>> padding_size_values = DecodeDeltas(
    503      proto.padding_size_deltas(), proto.padding_size(), number_of_deltas);
    504  RTC_PARSE_CHECK_OR_RETURN_EQ(padding_size_values.size(), number_of_deltas);
    505 
    506  // transport_sequence_number (RTP extension)
    507  std::vector<std::optional<uint64_t>> transport_sequence_number_values;
    508  {
    509    const std::optional<uint64_t> base_transport_sequence_number =
    510        proto.has_transport_sequence_number()
    511            ? proto.transport_sequence_number()
    512            : std::optional<uint64_t>();
    513    transport_sequence_number_values =
    514        DecodeDeltas(proto.transport_sequence_number_deltas(),
    515                     base_transport_sequence_number, number_of_deltas);
    516    RTC_PARSE_CHECK_OR_RETURN_EQ(transport_sequence_number_values.size(),
    517                                 number_of_deltas);
    518  }
    519 
    520  // transmission_time_offset (RTP extension)
    521  std::vector<std::optional<uint64_t>> transmission_time_offset_values;
    522  {
    523    const std::optional<uint64_t> unsigned_base_transmission_time_offset =
    524        proto.has_transmission_time_offset()
    525            ? ToUnsigned(proto.transmission_time_offset())
    526            : std::optional<uint64_t>();
    527    transmission_time_offset_values =
    528        DecodeDeltas(proto.transmission_time_offset_deltas(),
    529                     unsigned_base_transmission_time_offset, number_of_deltas);
    530    RTC_PARSE_CHECK_OR_RETURN_EQ(transmission_time_offset_values.size(),
    531                                 number_of_deltas);
    532  }
    533 
    534  // absolute_send_time (RTP extension)
    535  std::vector<std::optional<uint64_t>> absolute_send_time_values;
    536  {
    537    const std::optional<uint64_t> base_absolute_send_time =
    538        proto.has_absolute_send_time() ? proto.absolute_send_time()
    539                                       : std::optional<uint64_t>();
    540    absolute_send_time_values =
    541        DecodeDeltas(proto.absolute_send_time_deltas(), base_absolute_send_time,
    542                     number_of_deltas);
    543    RTC_PARSE_CHECK_OR_RETURN_EQ(absolute_send_time_values.size(),
    544                                 number_of_deltas);
    545  }
    546 
    547  // video_rotation (RTP extension)
    548  std::vector<std::optional<uint64_t>> video_rotation_values;
    549  {
    550    const std::optional<uint64_t> base_video_rotation =
    551        proto.has_video_rotation() ? proto.video_rotation()
    552                                   : std::optional<uint64_t>();
    553    video_rotation_values = DecodeDeltas(proto.video_rotation_deltas(),
    554                                         base_video_rotation, number_of_deltas);
    555    RTC_PARSE_CHECK_OR_RETURN_EQ(video_rotation_values.size(),
    556                                 number_of_deltas);
    557  }
    558 
    559  // audio_level (RTP extension)
    560  std::vector<std::optional<uint64_t>> audio_level_values;
    561  {
    562    const std::optional<uint64_t> base_audio_level =
    563        proto.has_audio_level() ? proto.audio_level()
    564                                : std::optional<uint64_t>();
    565    audio_level_values = DecodeDeltas(proto.audio_level_deltas(),
    566                                      base_audio_level, number_of_deltas);
    567    RTC_PARSE_CHECK_OR_RETURN_EQ(audio_level_values.size(), number_of_deltas);
    568  }
    569 
    570  // voice_activity (RTP extension)
    571  std::vector<std::optional<uint64_t>> voice_activity_values;
    572  {
    573    const std::optional<uint64_t> base_voice_activity =
    574        proto.has_voice_activity() ? proto.voice_activity()
    575                                   : std::optional<uint64_t>();
    576    voice_activity_values = DecodeDeltas(proto.voice_activity_deltas(),
    577                                         base_voice_activity, number_of_deltas);
    578    RTC_PARSE_CHECK_OR_RETURN_EQ(voice_activity_values.size(),
    579                                 number_of_deltas);
    580  }
    581 
    582  // Populate events from decoded deltas
    583  for (size_t i = 0; i < number_of_deltas; ++i) {
    584    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    585    RTC_PARSE_CHECK_OR_RETURN(marker_values[i].has_value());
    586    RTC_PARSE_CHECK_OR_RETURN(payload_type_values[i].has_value());
    587    RTC_PARSE_CHECK_OR_RETURN(sequence_number_values[i].has_value());
    588    RTC_PARSE_CHECK_OR_RETURN(rtp_timestamp_values[i].has_value());
    589    RTC_PARSE_CHECK_OR_RETURN(ssrc_values[i].has_value());
    590    RTC_PARSE_CHECK_OR_RETURN(payload_size_values[i].has_value());
    591    RTC_PARSE_CHECK_OR_RETURN(header_size_values[i].has_value());
    592    RTC_PARSE_CHECK_OR_RETURN(padding_size_values[i].has_value());
    593 
    594    int64_t timestamp_ms;
    595    RTC_PARSE_CHECK_OR_RETURN(
    596        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
    597 
    598    RTPHeader header;
    599    RTC_PARSE_CHECK_OR_RETURN(
    600        IsValueInRangeForNumericType<bool>(*marker_values[i]));
    601    header.markerBit = static_cast<bool>(*marker_values[i]);
    602    RTC_PARSE_CHECK_OR_RETURN(
    603        IsValueInRangeForNumericType<uint8_t>(*payload_type_values[i]));
    604    header.payloadType = static_cast<uint8_t>(*payload_type_values[i]);
    605    RTC_PARSE_CHECK_OR_RETURN(
    606        IsValueInRangeForNumericType<uint16_t>(*sequence_number_values[i]));
    607    header.sequenceNumber = static_cast<uint16_t>(*sequence_number_values[i]);
    608    RTC_PARSE_CHECK_OR_RETURN(
    609        IsValueInRangeForNumericType<uint32_t>(*rtp_timestamp_values[i]));
    610    header.timestamp = static_cast<uint32_t>(*rtp_timestamp_values[i]);
    611    RTC_PARSE_CHECK_OR_RETURN(
    612        IsValueInRangeForNumericType<uint32_t>(*ssrc_values[i]));
    613    header.ssrc = static_cast<uint32_t>(*ssrc_values[i]);
    614    header.numCSRCs = 0;  // TODO(terelius): Implement CSRC.
    615    RTC_PARSE_CHECK_OR_RETURN(
    616        IsValueInRangeForNumericType<size_t>(*padding_size_values[i]));
    617    header.paddingLength = static_cast<size_t>(*padding_size_values[i]);
    618    RTC_PARSE_CHECK_OR_RETURN(
    619        IsValueInRangeForNumericType<size_t>(*header_size_values[i]));
    620    header.headerLength = static_cast<size_t>(*header_size_values[i]);
    621    // TODO(terelius): Should we implement payload_type_frequency?
    622    if (transport_sequence_number_values.size() > i &&
    623        transport_sequence_number_values[i].has_value()) {
    624      header.extension.hasTransportSequenceNumber = true;
    625      RTC_PARSE_CHECK_OR_RETURN(IsValueInRangeForNumericType<uint16_t>(
    626          transport_sequence_number_values[i].value()));
    627      header.extension.transportSequenceNumber =
    628          static_cast<uint16_t>(transport_sequence_number_values[i].value());
    629    }
    630    if (transmission_time_offset_values.size() > i &&
    631        transmission_time_offset_values[i].has_value()) {
    632      header.extension.hasTransmissionTimeOffset = true;
    633      int32_t transmission_time_offset;
    634      RTC_PARSE_CHECK_OR_RETURN(
    635          ToSigned(transmission_time_offset_values[i].value(),
    636                   &transmission_time_offset));
    637      header.extension.transmissionTimeOffset = transmission_time_offset;
    638    }
    639    if (absolute_send_time_values.size() > i &&
    640        absolute_send_time_values[i].has_value()) {
    641      header.extension.hasAbsoluteSendTime = true;
    642      RTC_PARSE_CHECK_OR_RETURN(IsValueInRangeForNumericType<uint32_t>(
    643          absolute_send_time_values[i].value()));
    644      header.extension.absoluteSendTime =
    645          static_cast<uint32_t>(absolute_send_time_values[i].value());
    646    }
    647    if (video_rotation_values.size() > i &&
    648        video_rotation_values[i].has_value()) {
    649      header.extension.hasVideoRotation = true;
    650      RTC_PARSE_CHECK_OR_RETURN(IsValueInRangeForNumericType<uint8_t>(
    651          video_rotation_values[i].value()));
    652      header.extension.videoRotation = ConvertCVOByteToVideoRotation(
    653          static_cast<uint8_t>(video_rotation_values[i].value()));
    654    }
    655    if (audio_level_values.size() > i && audio_level_values[i].has_value()) {
    656      RTC_PARSE_CHECK_OR_RETURN(voice_activity_values.size() > i &&
    657                                voice_activity_values[i].has_value());
    658      RTC_PARSE_CHECK_OR_RETURN(
    659          IsValueInRangeForNumericType<bool>(voice_activity_values[i].value()));
    660      bool voice_activity = static_cast<bool>(voice_activity_values[i].value());
    661      RTC_PARSE_CHECK_OR_RETURN(
    662          IsValueInRangeForNumericType<int>(audio_level_values[i].value()));
    663      int audio_level = static_cast<int>(audio_level_values[i].value());
    664      RTC_PARSE_CHECK_OR_RETURN_LE(audio_level, 0x7F);
    665      header.extension.set_audio_level(AudioLevel(voice_activity, audio_level));
    666    } else {
    667      RTC_PARSE_CHECK_OR_RETURN(voice_activity_values.size() <= i ||
    668                                !voice_activity_values[i].has_value());
    669    }
    670    LoggedType logged_packet(Timestamp::Millis(timestamp_ms), header,
    671                             header.headerLength,
    672                             payload_size_values[i].value() +
    673                                 header.headerLength + header.paddingLength);
    674    if (!dependency_descriptor_wire_format[i + 1].empty()) {
    675      logged_packet.rtp.dependency_descriptor_wire_format =
    676          dependency_descriptor_wire_format[i + 1];
    677    }
    678    (*rtp_packets_map)[header.ssrc].push_back(std::move(logged_packet));
    679  }
    680  return ParsedRtcEventLog::ParseStatus::Success();
    681 }
    682 
    683 template <typename ProtoType, typename LoggedType>
    684 ParsedRtcEventLog::ParseStatus StoreRtcpPackets(
    685    const ProtoType& proto,
    686    std::vector<LoggedType>* rtcp_packets,
    687    bool remove_duplicates) {
    688  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
    689  RTC_PARSE_CHECK_OR_RETURN(proto.has_raw_packet());
    690 
    691  // TODO(terelius): Incoming RTCP may be delivered once for audio and once
    692  // for video. As a work around, we remove the duplicated packets since they
    693  // cause problems when analyzing the log or feeding it into the transport
    694  // feedback adapter.
    695  if (!remove_duplicates || rtcp_packets->empty() ||
    696      !IdenticalRtcpContents(rtcp_packets->back().rtcp.raw_data,
    697                             proto.raw_packet())) {
    698    // Base event
    699    rtcp_packets->emplace_back(Timestamp::Millis(proto.timestamp_ms()),
    700                               proto.raw_packet());
    701  }
    702 
    703  const size_t number_of_deltas =
    704      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
    705  if (number_of_deltas == 0) {
    706    return ParsedRtcEventLog::ParseStatus::Success();
    707  }
    708 
    709  // timestamp_ms
    710  std::vector<std::optional<uint64_t>> timestamp_ms_values =
    711      DecodeDeltas(proto.timestamp_ms_deltas(),
    712                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
    713  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
    714 
    715  // raw_packet
    716  RTC_PARSE_CHECK_OR_RETURN(proto.has_raw_packet_blobs());
    717  std::vector<absl::string_view> raw_packet_values =
    718      DecodeBlobs(proto.raw_packet_blobs(), number_of_deltas);
    719  RTC_PARSE_CHECK_OR_RETURN_EQ(raw_packet_values.size(), number_of_deltas);
    720 
    721  // Populate events from decoded deltas
    722  for (size_t i = 0; i < number_of_deltas; ++i) {
    723    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
    724    int64_t timestamp_ms;
    725    RTC_PARSE_CHECK_OR_RETURN(
    726        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
    727 
    728    // TODO(terelius): Incoming RTCP may be delivered once for audio and once
    729    // for video. As a work around, we remove the duplicated packets since they
    730    // cause problems when analyzing the log or feeding it into the transport
    731    // feedback adapter.
    732    if (remove_duplicates && !rtcp_packets->empty() &&
    733        IdenticalRtcpContents(rtcp_packets->back().rtcp.raw_data,
    734                              raw_packet_values[i])) {
    735      continue;
    736    }
    737    std::string data(raw_packet_values[i]);
    738    rtcp_packets->emplace_back(Timestamp::Millis(timestamp_ms), data);
    739  }
    740  return ParsedRtcEventLog::ParseStatus::Success();
    741 }
    742 
    743 ParsedRtcEventLog::ParseStatus StoreRtcpBlocks(
    744    int64_t timestamp_us,
    745    const uint8_t* packet_begin,
    746    const uint8_t* packet_end,
    747    std::vector<LoggedRtcpPacketSenderReport>* sr_list,
    748    std::vector<LoggedRtcpPacketReceiverReport>* rr_list,
    749    std::vector<LoggedRtcpPacketExtendedReports>* xr_list,
    750    std::vector<LoggedRtcpPacketRemb>* remb_list,
    751    std::vector<LoggedRtcpPacketNack>* nack_list,
    752    std::vector<LoggedRtcpPacketFir>* fir_list,
    753    std::vector<LoggedRtcpPacketPli>* pli_list,
    754    std::vector<LoggedRtcpPacketBye>* bye_list,
    755    std::vector<LoggedRtcpPacketTransportFeedback>* transport_feedback_list,
    756    std::vector<LoggedRtcpCongestionControlFeedback>* congestion_feedback_list,
    757    std::vector<LoggedRtcpPacketLossNotification>* loss_notification_list) {
    758  Timestamp timestamp = Timestamp::Micros(timestamp_us);
    759  rtcp::CommonHeader header;
    760  for (const uint8_t* block = packet_begin; block < packet_end;
    761       block = header.NextPacket()) {
    762    RTC_PARSE_CHECK_OR_RETURN(header.Parse(block, packet_end - block));
    763    if (header.type() == rtcp::TransportFeedback::kPacketType &&
    764        header.fmt() == rtcp::TransportFeedback::kFeedbackMessageType) {
    765      LoggedRtcpPacketTransportFeedback parsed_block;
    766      parsed_block.timestamp = timestamp;
    767      RTC_PARSE_CHECK_OR_RETURN(parsed_block.transport_feedback.Parse(header));
    768      transport_feedback_list->push_back(std::move(parsed_block));
    769    } else if (header.type() == rtcp::Rtpfb::kPacketType &&
    770               header.fmt() ==
    771                   rtcp::CongestionControlFeedback::kFeedbackMessageType) {
    772      rtcp::CongestionControlFeedback feedback;
    773      RTC_PARSE_CHECK_OR_RETURN(feedback.Parse(header));
    774      congestion_feedback_list->emplace_back(timestamp, std::move(feedback));
    775    } else if (header.type() == rtcp::SenderReport::kPacketType) {
    776      LoggedRtcpPacketSenderReport parsed_block;
    777      parsed_block.timestamp = timestamp;
    778      RTC_PARSE_CHECK_OR_RETURN(parsed_block.sr.Parse(header));
    779      sr_list->push_back(std::move(parsed_block));
    780    } else if (header.type() == rtcp::ReceiverReport::kPacketType) {
    781      LoggedRtcpPacketReceiverReport parsed_block;
    782      parsed_block.timestamp = timestamp;
    783      RTC_PARSE_CHECK_OR_RETURN(parsed_block.rr.Parse(header));
    784      rr_list->push_back(std::move(parsed_block));
    785    } else if (header.type() == rtcp::ExtendedReports::kPacketType) {
    786      LoggedRtcpPacketExtendedReports parsed_block;
    787      parsed_block.timestamp = timestamp;
    788      RTC_PARSE_CHECK_OR_RETURN(parsed_block.xr.Parse(header));
    789      xr_list->push_back(std::move(parsed_block));
    790    } else if (header.type() == rtcp::Fir::kPacketType &&
    791               header.fmt() == rtcp::Fir::kFeedbackMessageType) {
    792      LoggedRtcpPacketFir parsed_block;
    793      parsed_block.timestamp = timestamp;
    794      RTC_PARSE_CHECK_OR_RETURN(parsed_block.fir.Parse(header));
    795      fir_list->push_back(std::move(parsed_block));
    796    } else if (header.type() == rtcp::Pli::kPacketType &&
    797               header.fmt() == rtcp::Pli::kFeedbackMessageType) {
    798      LoggedRtcpPacketPli parsed_block;
    799      parsed_block.timestamp = timestamp;
    800      RTC_PARSE_CHECK_OR_RETURN(parsed_block.pli.Parse(header));
    801      pli_list->push_back(std::move(parsed_block));
    802    } else if (header.type() == rtcp::Bye::kPacketType) {
    803      LoggedRtcpPacketBye parsed_block;
    804      parsed_block.timestamp = timestamp;
    805      RTC_PARSE_CHECK_OR_RETURN(parsed_block.bye.Parse(header));
    806      bye_list->push_back(std::move(parsed_block));
    807    } else if (header.type() == rtcp::Psfb::kPacketType &&
    808               header.fmt() == rtcp::Psfb::kAfbMessageType) {
    809      bool type_found = false;
    810      if (!type_found) {
    811        LoggedRtcpPacketRemb parsed_block;
    812        parsed_block.timestamp = timestamp;
    813        if (parsed_block.remb.Parse(header)) {
    814          remb_list->push_back(std::move(parsed_block));
    815          type_found = true;
    816        }
    817      }
    818      if (!type_found) {
    819        LoggedRtcpPacketLossNotification parsed_block;
    820        parsed_block.timestamp = timestamp;
    821        if (parsed_block.loss_notification.Parse(header)) {
    822          loss_notification_list->push_back(std::move(parsed_block));
    823          type_found = true;
    824        }
    825      }
    826      // We ignore other application-layer feedback types.
    827    } else if (header.type() == rtcp::Nack::kPacketType &&
    828               header.fmt() == rtcp::Nack::kFeedbackMessageType) {
    829      LoggedRtcpPacketNack parsed_block;
    830      parsed_block.timestamp = timestamp;
    831      RTC_PARSE_CHECK_OR_RETURN(parsed_block.nack.Parse(header));
    832      nack_list->push_back(std::move(parsed_block));
    833    }
    834  }
    835  return ParsedRtcEventLog::ParseStatus::Success();
    836 }
    837 
    838 }  // namespace
    839 
    840 // Conversion functions for version 2 of the wire format.
    841 BandwidthUsage GetRuntimeDetectorState(
    842    rtclog2::DelayBasedBweUpdates::DetectorState detector_state) {
    843  switch (detector_state) {
    844    case rtclog2::DelayBasedBweUpdates::BWE_NORMAL:
    845      return BandwidthUsage::kBwNormal;
    846    case rtclog2::DelayBasedBweUpdates::BWE_UNDERUSING:
    847      return BandwidthUsage::kBwUnderusing;
    848    case rtclog2::DelayBasedBweUpdates::BWE_OVERUSING:
    849      return BandwidthUsage::kBwOverusing;
    850    case rtclog2::DelayBasedBweUpdates::BWE_UNKNOWN_STATE:
    851      break;
    852  }
    853  RTC_DCHECK_NOTREACHED();
    854  return BandwidthUsage::kBwNormal;
    855 }
    856 
    857 ProbeFailureReason GetRuntimeProbeFailureReason(
    858    rtclog2::BweProbeResultFailure::FailureReason failure) {
    859  switch (failure) {
    860    case rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_INTERVAL:
    861      return ProbeFailureReason::kInvalidSendReceiveInterval;
    862    case rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_RATIO:
    863      return ProbeFailureReason::kInvalidSendReceiveRatio;
    864    case rtclog2::BweProbeResultFailure::TIMEOUT:
    865      return ProbeFailureReason::kTimeout;
    866    case rtclog2::BweProbeResultFailure::UNKNOWN:
    867      break;
    868  }
    869  RTC_DCHECK_NOTREACHED();
    870  return ProbeFailureReason::kTimeout;
    871 }
    872 
    873 DtlsTransportState GetRuntimeDtlsTransportState(
    874    rtclog2::DtlsTransportStateEvent::DtlsTransportState state) {
    875  switch (state) {
    876    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_NEW:
    877      return DtlsTransportState::kNew;
    878    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTING:
    879      return DtlsTransportState::kConnecting;
    880    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTED:
    881      return DtlsTransportState::kConnected;
    882    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CLOSED:
    883      return DtlsTransportState::kClosed;
    884    case rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_FAILED:
    885      return DtlsTransportState::kFailed;
    886    case rtclog2::DtlsTransportStateEvent::UNKNOWN_DTLS_TRANSPORT_STATE:
    887      RTC_DCHECK_NOTREACHED();
    888      return DtlsTransportState::kNumValues;
    889  }
    890  RTC_DCHECK_NOTREACHED();
    891  return DtlsTransportState::kNumValues;
    892 }
    893 
    894 IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType(
    895    rtclog2::IceCandidatePairConfig::IceCandidatePairConfigType type) {
    896  switch (type) {
    897    case rtclog2::IceCandidatePairConfig::ADDED:
    898      return IceCandidatePairConfigType::kAdded;
    899    case rtclog2::IceCandidatePairConfig::UPDATED:
    900      return IceCandidatePairConfigType::kUpdated;
    901    case rtclog2::IceCandidatePairConfig::DESTROYED:
    902      return IceCandidatePairConfigType::kDestroyed;
    903    case rtclog2::IceCandidatePairConfig::SELECTED:
    904      return IceCandidatePairConfigType::kSelected;
    905    case rtclog2::IceCandidatePairConfig::UNKNOWN_CONFIG_TYPE:
    906      break;
    907  }
    908  RTC_DCHECK_NOTREACHED();
    909  return IceCandidatePairConfigType::kAdded;
    910 }
    911 
    912 IceCandidateType GetRuntimeIceCandidateType(
    913    rtclog2::IceCandidatePairConfig::IceCandidateType type) {
    914  switch (type) {
    915    case rtclog2::IceCandidatePairConfig::LOCAL:
    916      return IceCandidateType::kHost;
    917    case rtclog2::IceCandidatePairConfig::STUN:
    918      return IceCandidateType::kSrflx;
    919    case rtclog2::IceCandidatePairConfig::PRFLX:
    920      return IceCandidateType::kPrflx;
    921    case rtclog2::IceCandidatePairConfig::RELAY:
    922      return IceCandidateType::kRelay;
    923    default:
    924      RTC_DCHECK_NOTREACHED();
    925      return IceCandidateType::kHost;
    926  }
    927 }
    928 
    929 bool GetRuntimeIceCandidateType(
    930    rtclog2::IceCandidatePairConfig::IceCandidateType log_type,
    931    IceCandidateType& parsed_type) {
    932  switch (log_type) {
    933    case rtclog2::IceCandidatePairConfig::LOCAL:
    934      parsed_type = IceCandidateType::kHost;
    935      break;
    936    case rtclog2::IceCandidatePairConfig::STUN:
    937      parsed_type = IceCandidateType::kSrflx;
    938      break;
    939    case rtclog2::IceCandidatePairConfig::PRFLX:
    940      parsed_type = IceCandidateType::kPrflx;
    941      break;
    942    case rtclog2::IceCandidatePairConfig::RELAY:
    943      parsed_type = IceCandidateType::kRelay;
    944      break;
    945    default:
    946      return false;
    947  }
    948  return true;
    949 }
    950 
    951 IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
    952    rtclog2::IceCandidatePairConfig::Protocol protocol) {
    953  switch (protocol) {
    954    case rtclog2::IceCandidatePairConfig::UDP:
    955      return IceCandidatePairProtocol::kUdp;
    956    case rtclog2::IceCandidatePairConfig::TCP:
    957      return IceCandidatePairProtocol::kTcp;
    958    case rtclog2::IceCandidatePairConfig::SSLTCP:
    959      return IceCandidatePairProtocol::kSsltcp;
    960    case rtclog2::IceCandidatePairConfig::TLS:
    961      return IceCandidatePairProtocol::kTls;
    962    case rtclog2::IceCandidatePairConfig::UNKNOWN_PROTOCOL:
    963      return IceCandidatePairProtocol::kUnknown;
    964  }
    965  RTC_DCHECK_NOTREACHED();
    966  return IceCandidatePairProtocol::kUnknown;
    967 }
    968 
    969 IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
    970    rtclog2::IceCandidatePairConfig::AddressFamily address_family) {
    971  switch (address_family) {
    972    case rtclog2::IceCandidatePairConfig::IPV4:
    973      return IceCandidatePairAddressFamily::kIpv4;
    974    case rtclog2::IceCandidatePairConfig::IPV6:
    975      return IceCandidatePairAddressFamily::kIpv6;
    976    case rtclog2::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY:
    977      return IceCandidatePairAddressFamily::kUnknown;
    978  }
    979  RTC_DCHECK_NOTREACHED();
    980  return IceCandidatePairAddressFamily::kUnknown;
    981 }
    982 
    983 IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
    984    rtclog2::IceCandidatePairConfig::NetworkType network_type) {
    985  switch (network_type) {
    986    case rtclog2::IceCandidatePairConfig::ETHERNET:
    987      return IceCandidateNetworkType::kEthernet;
    988    case rtclog2::IceCandidatePairConfig::LOOPBACK:
    989      return IceCandidateNetworkType::kLoopback;
    990    case rtclog2::IceCandidatePairConfig::WIFI:
    991      return IceCandidateNetworkType::kWifi;
    992    case rtclog2::IceCandidatePairConfig::VPN:
    993      return IceCandidateNetworkType::kVpn;
    994    case rtclog2::IceCandidatePairConfig::CELLULAR:
    995      return IceCandidateNetworkType::kCellular;
    996    case rtclog2::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE:
    997      return IceCandidateNetworkType::kUnknown;
    998  }
    999  RTC_DCHECK_NOTREACHED();
   1000  return IceCandidateNetworkType::kUnknown;
   1001 }
   1002 
   1003 IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
   1004    rtclog2::IceCandidatePairEvent::IceCandidatePairEventType type) {
   1005  switch (type) {
   1006    case rtclog2::IceCandidatePairEvent::CHECK_SENT:
   1007      return IceCandidatePairEventType::kCheckSent;
   1008    case rtclog2::IceCandidatePairEvent::CHECK_RECEIVED:
   1009      return IceCandidatePairEventType::kCheckReceived;
   1010    case rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_SENT:
   1011      return IceCandidatePairEventType::kCheckResponseSent;
   1012    case rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED:
   1013      return IceCandidatePairEventType::kCheckResponseReceived;
   1014    case rtclog2::IceCandidatePairEvent::UNKNOWN_CHECK_TYPE:
   1015      break;
   1016  }
   1017  RTC_DCHECK_NOTREACHED();
   1018  return IceCandidatePairEventType::kCheckSent;
   1019 }
   1020 
   1021 std::vector<RtpExtension> GetRuntimeRtpHeaderExtensionConfig(
   1022    const rtclog2::RtpHeaderExtensionConfig& proto_header_extensions) {
   1023  std::vector<RtpExtension> rtp_extensions;
   1024  if (proto_header_extensions.has_transmission_time_offset_id()) {
   1025    rtp_extensions.emplace_back(
   1026        RtpExtension::kTimestampOffsetUri,
   1027        proto_header_extensions.transmission_time_offset_id());
   1028  }
   1029  if (proto_header_extensions.has_absolute_send_time_id()) {
   1030    rtp_extensions.emplace_back(
   1031        RtpExtension::kAbsSendTimeUri,
   1032        proto_header_extensions.absolute_send_time_id());
   1033  }
   1034  if (proto_header_extensions.has_transport_sequence_number_id()) {
   1035    rtp_extensions.emplace_back(
   1036        RtpExtension::kTransportSequenceNumberUri,
   1037        proto_header_extensions.transport_sequence_number_id());
   1038  }
   1039  if (proto_header_extensions.has_audio_level_id()) {
   1040    rtp_extensions.emplace_back(RtpExtension::kAudioLevelUri,
   1041                                proto_header_extensions.audio_level_id());
   1042  }
   1043  if (proto_header_extensions.has_video_rotation_id()) {
   1044    rtp_extensions.emplace_back(RtpExtension::kVideoRotationUri,
   1045                                proto_header_extensions.video_rotation_id());
   1046  }
   1047  if (proto_header_extensions.has_dependency_descriptor_id()) {
   1048    rtp_extensions.emplace_back(
   1049        RtpExtension::kDependencyDescriptorUri,
   1050        proto_header_extensions.dependency_descriptor_id());
   1051  }
   1052  return rtp_extensions;
   1053 }
   1054 // End of conversion functions.
   1055 
   1056 LoggedPacketInfo::LoggedPacketInfo(const LoggedRtpPacket& rtp,
   1057                                   LoggedMediaType media_type,
   1058                                   bool rtx,
   1059                                   Timestamp capture_time)
   1060    : ssrc(rtp.header.ssrc),
   1061      stream_seq_no(rtp.header.sequenceNumber),
   1062      size(static_cast<uint16_t>(rtp.total_length)),
   1063      payload_size(static_cast<uint16_t>(rtp.total_length -
   1064                                         rtp.header.paddingLength -
   1065                                         rtp.header.headerLength)),
   1066      padding_size(static_cast<uint16_t>(rtp.header.paddingLength)),
   1067      payload_type(rtp.header.payloadType),
   1068      media_type(media_type),
   1069      rtx(rtx),
   1070      marker_bit(rtp.header.markerBit),
   1071      has_transport_seq_no(rtp.header.extension.hasTransportSequenceNumber),
   1072      transport_seq_no(static_cast<uint16_t>(
   1073          has_transport_seq_no ? rtp.header.extension.transportSequenceNumber
   1074                               : 0)),
   1075      capture_time(capture_time),
   1076      log_packet_time(Timestamp::Micros(rtp.log_time_us())),
   1077      reported_send_time(rtp.header.extension.hasAbsoluteSendTime
   1078                             ? rtp.header.extension.GetAbsoluteSendTimestamp()
   1079                             : Timestamp::MinusInfinity()) {}
   1080 
   1081 LoggedPacketInfo::LoggedPacketInfo(const LoggedPacketInfo&) = default;
   1082 
   1083 LoggedPacketInfo::~LoggedPacketInfo() {}
   1084 
   1085 ParsedRtcEventLog::~ParsedRtcEventLog() = default;
   1086 
   1087 ParsedRtcEventLog::LoggedRtpStreamIncoming::LoggedRtpStreamIncoming() = default;
   1088 ParsedRtcEventLog::LoggedRtpStreamIncoming::LoggedRtpStreamIncoming(
   1089    const LoggedRtpStreamIncoming& rhs) = default;
   1090 ParsedRtcEventLog::LoggedRtpStreamIncoming::~LoggedRtpStreamIncoming() =
   1091    default;
   1092 
   1093 ParsedRtcEventLog::LoggedRtpStreamOutgoing::LoggedRtpStreamOutgoing() = default;
   1094 ParsedRtcEventLog::LoggedRtpStreamOutgoing::LoggedRtpStreamOutgoing(
   1095    const LoggedRtpStreamOutgoing& rhs) = default;
   1096 ParsedRtcEventLog::LoggedRtpStreamOutgoing::~LoggedRtpStreamOutgoing() =
   1097    default;
   1098 
   1099 ParsedRtcEventLog::LoggedRtpStreamView::LoggedRtpStreamView(
   1100    uint32_t ssrc,
   1101    const std::vector<LoggedRtpPacketIncoming>& packets)
   1102    : ssrc(ssrc), packet_view() {
   1103  for (const LoggedRtpPacketIncoming& packet : packets) {
   1104    packet_view.push_back(&(packet.rtp));
   1105  }
   1106 }
   1107 
   1108 ParsedRtcEventLog::LoggedRtpStreamView::LoggedRtpStreamView(
   1109    uint32_t ssrc,
   1110    const std::vector<LoggedRtpPacketOutgoing>& packets)
   1111    : ssrc(ssrc), packet_view() {
   1112  for (const LoggedRtpPacketOutgoing& packet : packets) {
   1113    packet_view.push_back(&(packet.rtp));
   1114  }
   1115 }
   1116 
   1117 ParsedRtcEventLog::LoggedRtpStreamView::LoggedRtpStreamView(
   1118    const LoggedRtpStreamView&) = default;
   1119 
   1120 // Return default values for header extensions, to use on streams without stored
   1121 // mapping data. Currently this only applies to audio streams, since the mapping
   1122 // is not stored in the event log.
   1123 // TODO(ivoc): Remove this once this mapping is stored in the event log for
   1124 //             audio streams. Tracking bug: webrtc:6399
   1125 RtpHeaderExtensionMap ParsedRtcEventLog::GetDefaultHeaderExtensionMap() {
   1126  // Values from before the default RTP header extension IDs were removed.
   1127  constexpr int kAudioLevelDefaultId = 1;
   1128  constexpr int kTimestampOffsetDefaultId = 2;
   1129  constexpr int kAbsSendTimeDefaultId = 3;
   1130  constexpr int kVideoRotationDefaultId = 4;
   1131  constexpr int kTransportSequenceNumberDefaultId = 5;
   1132  constexpr int kPlayoutDelayDefaultId = 6;
   1133  constexpr int kVideoContentTypeDefaultId = 7;
   1134  constexpr int kVideoTimingDefaultId = 8;
   1135  constexpr int kDependencyDescriptorDefaultId = 9;
   1136 
   1137  RtpHeaderExtensionMap default_map(/*extmap_allow_mixed=*/true);
   1138  default_map.Register<AudioLevelExtension>(kAudioLevelDefaultId);
   1139  default_map.Register<TransmissionOffset>(kTimestampOffsetDefaultId);
   1140  default_map.Register<AbsoluteSendTime>(kAbsSendTimeDefaultId);
   1141  default_map.Register<VideoOrientation>(kVideoRotationDefaultId);
   1142  default_map.Register<TransportSequenceNumber>(
   1143      kTransportSequenceNumberDefaultId);
   1144  default_map.Register<PlayoutDelayLimits>(kPlayoutDelayDefaultId);
   1145  default_map.Register<VideoContentTypeExtension>(kVideoContentTypeDefaultId);
   1146  default_map.Register<VideoTimingExtension>(kVideoTimingDefaultId);
   1147  default_map.Register<RtpDependencyDescriptorExtension>(
   1148      kDependencyDescriptorDefaultId);
   1149  return default_map;
   1150 }
   1151 
   1152 ParsedRtcEventLog::ParsedRtcEventLog(
   1153    UnconfiguredHeaderExtensions parse_unconfigured_header_extensions,
   1154    bool allow_incomplete_logs)
   1155    : parse_unconfigured_header_extensions_(
   1156          parse_unconfigured_header_extensions),
   1157      allow_incomplete_logs_(allow_incomplete_logs) {
   1158  Clear();
   1159 }
   1160 
   1161 void ParsedRtcEventLog::Clear() {
   1162  default_extension_map_ = GetDefaultHeaderExtensionMap();
   1163 
   1164  incoming_rtx_ssrcs_.clear();
   1165  incoming_video_ssrcs_.clear();
   1166  incoming_audio_ssrcs_.clear();
   1167  outgoing_rtx_ssrcs_.clear();
   1168  outgoing_video_ssrcs_.clear();
   1169  outgoing_audio_ssrcs_.clear();
   1170 
   1171  incoming_rtp_packets_map_.clear();
   1172  outgoing_rtp_packets_map_.clear();
   1173  incoming_rtp_packets_by_ssrc_.clear();
   1174  outgoing_rtp_packets_by_ssrc_.clear();
   1175  incoming_rtp_packet_views_by_ssrc_.clear();
   1176  outgoing_rtp_packet_views_by_ssrc_.clear();
   1177 
   1178  incoming_rtcp_packets_.clear();
   1179  outgoing_rtcp_packets_.clear();
   1180 
   1181  incoming_rr_.clear();
   1182  outgoing_rr_.clear();
   1183  incoming_sr_.clear();
   1184  outgoing_sr_.clear();
   1185  incoming_nack_.clear();
   1186  outgoing_nack_.clear();
   1187  incoming_remb_.clear();
   1188  outgoing_remb_.clear();
   1189  incoming_transport_feedback_.clear();
   1190  outgoing_transport_feedback_.clear();
   1191  incoming_loss_notification_.clear();
   1192  outgoing_loss_notification_.clear();
   1193 
   1194  start_log_events_.clear();
   1195  stop_log_events_.clear();
   1196  audio_playout_events_.clear();
   1197  neteq_set_minimum_delay_events_.clear();
   1198  audio_network_adaptation_events_.clear();
   1199  bwe_probe_cluster_created_events_.clear();
   1200  bwe_probe_failure_events_.clear();
   1201  bwe_probe_success_events_.clear();
   1202  bwe_delay_updates_.clear();
   1203  bwe_loss_updates_.clear();
   1204  dtls_transport_states_.clear();
   1205  dtls_writable_states_.clear();
   1206  decoded_frames_.clear();
   1207  alr_state_events_.clear();
   1208  ice_candidate_pair_configs_.clear();
   1209  ice_candidate_pair_events_.clear();
   1210  audio_recv_configs_.clear();
   1211  audio_send_configs_.clear();
   1212  video_recv_configs_.clear();
   1213  video_send_configs_.clear();
   1214 
   1215  last_incoming_rtcp_packet_.clear();
   1216 
   1217  first_timestamp_ = Timestamp::PlusInfinity();
   1218  last_timestamp_ = Timestamp::MinusInfinity();
   1219  first_log_segment_ = LogSegment(0, std::numeric_limits<int64_t>::max());
   1220 
   1221  incoming_rtp_extensions_maps_.clear();
   1222  outgoing_rtp_extensions_maps_.clear();
   1223 }
   1224 
   1225 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseFile(
   1226    absl::string_view filename) {
   1227  FileWrapper file = FileWrapper::OpenReadOnly(filename);
   1228  if (!file.is_open()) {
   1229    RTC_LOG(LS_WARNING) << "Could not open file " << filename
   1230                        << " for reading.";
   1231    RTC_PARSE_CHECK_OR_RETURN(file.is_open());
   1232  }
   1233 
   1234  // Compute file size.
   1235  std::optional<size_t> file_size = file.FileSize();
   1236  RTC_PARSE_CHECK_OR_RETURN(file_size.has_value());
   1237  RTC_PARSE_CHECK_OR_RETURN_GE(*file_size, 0u);
   1238  RTC_PARSE_CHECK_OR_RETURN_LE(*file_size, kMaxLogSize);
   1239 
   1240  // Read file into memory.
   1241  std::string buffer(*file_size, '\0');
   1242  size_t bytes_read = file.Read(&buffer[0], buffer.size());
   1243  if (bytes_read != *file_size) {
   1244    RTC_LOG(LS_WARNING) << "Failed to read file " << filename;
   1245    RTC_PARSE_CHECK_OR_RETURN_EQ(bytes_read, *file_size);
   1246  }
   1247 
   1248  return ParseStream(buffer);
   1249 }
   1250 
   1251 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseString(
   1252    absl::string_view s) {
   1253  return ParseStream(s);
   1254 }
   1255 
   1256 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStream(
   1257    absl::string_view s) {
   1258  Clear();
   1259  ParseStatus status = ParseStreamInternal(s);
   1260 
   1261  // Cache the configured SSRCs.
   1262  for (const auto& video_recv_config : video_recv_configs()) {
   1263    incoming_video_ssrcs_.insert(video_recv_config.config.remote_ssrc);
   1264    incoming_video_ssrcs_.insert(video_recv_config.config.rtx_ssrc);
   1265    incoming_rtx_ssrcs_.insert(video_recv_config.config.rtx_ssrc);
   1266  }
   1267  for (const auto& video_send_config : video_send_configs()) {
   1268    outgoing_video_ssrcs_.insert(video_send_config.config.local_ssrc);
   1269    outgoing_video_ssrcs_.insert(video_send_config.config.rtx_ssrc);
   1270    outgoing_rtx_ssrcs_.insert(video_send_config.config.rtx_ssrc);
   1271  }
   1272  for (const auto& audio_recv_config : audio_recv_configs()) {
   1273    incoming_audio_ssrcs_.insert(audio_recv_config.config.remote_ssrc);
   1274  }
   1275  for (const auto& audio_send_config : audio_send_configs()) {
   1276    outgoing_audio_ssrcs_.insert(audio_send_config.config.local_ssrc);
   1277  }
   1278 
   1279  // ParseStreamInternal stores the RTP packets in a map indexed by SSRC.
   1280  // Since we dont need rapid lookup based on SSRC after parsing, we move the
   1281  // packets_streams from map to vector.
   1282  incoming_rtp_packets_by_ssrc_.reserve(incoming_rtp_packets_map_.size());
   1283  for (auto& kv : incoming_rtp_packets_map_) {
   1284    incoming_rtp_packets_by_ssrc_.emplace_back(LoggedRtpStreamIncoming());
   1285    incoming_rtp_packets_by_ssrc_.back().ssrc = kv.first;
   1286    incoming_rtp_packets_by_ssrc_.back().incoming_packets =
   1287        std::move(kv.second);
   1288  }
   1289  incoming_rtp_packets_map_.clear();
   1290  outgoing_rtp_packets_by_ssrc_.reserve(outgoing_rtp_packets_map_.size());
   1291  for (auto& kv : outgoing_rtp_packets_map_) {
   1292    outgoing_rtp_packets_by_ssrc_.emplace_back(LoggedRtpStreamOutgoing());
   1293    outgoing_rtp_packets_by_ssrc_.back().ssrc = kv.first;
   1294    outgoing_rtp_packets_by_ssrc_.back().outgoing_packets =
   1295        std::move(kv.second);
   1296  }
   1297  outgoing_rtp_packets_map_.clear();
   1298 
   1299  // Build PacketViews for easier iteration over RTP packets.
   1300  for (const auto& stream : incoming_rtp_packets_by_ssrc_) {
   1301    incoming_rtp_packet_views_by_ssrc_.emplace_back(
   1302        LoggedRtpStreamView(stream.ssrc, stream.incoming_packets));
   1303  }
   1304  for (const auto& stream : outgoing_rtp_packets_by_ssrc_) {
   1305    outgoing_rtp_packet_views_by_ssrc_.emplace_back(
   1306        LoggedRtpStreamView(stream.ssrc, stream.outgoing_packets));
   1307  }
   1308 
   1309  // Set up convenience wrappers around the most commonly used RTCP types.
   1310  for (const auto& incoming : incoming_rtcp_packets_) {
   1311    const int64_t timestamp_us = incoming.rtcp.timestamp.us();
   1312    const uint8_t* packet_begin = incoming.rtcp.raw_data.data();
   1313    const uint8_t* packet_end = packet_begin + incoming.rtcp.raw_data.size();
   1314    auto store_rtcp_status = StoreRtcpBlocks(
   1315        timestamp_us, packet_begin, packet_end, &incoming_sr_, &incoming_rr_,
   1316        &incoming_xr_, &incoming_remb_, &incoming_nack_, &incoming_fir_,
   1317        &incoming_pli_, &incoming_bye_, &incoming_transport_feedback_,
   1318        &incoming_congestion_feedback_, &incoming_loss_notification_);
   1319    RTC_RETURN_IF_ERROR(store_rtcp_status);
   1320  }
   1321 
   1322  for (const auto& outgoing : outgoing_rtcp_packets_) {
   1323    const int64_t timestamp_us = outgoing.rtcp.timestamp.us();
   1324    const uint8_t* packet_begin = outgoing.rtcp.raw_data.data();
   1325    const uint8_t* packet_end = packet_begin + outgoing.rtcp.raw_data.size();
   1326    auto store_rtcp_status = StoreRtcpBlocks(
   1327        timestamp_us, packet_begin, packet_end, &outgoing_sr_, &outgoing_rr_,
   1328        &outgoing_xr_, &outgoing_remb_, &outgoing_nack_, &outgoing_fir_,
   1329        &outgoing_pli_, &outgoing_bye_, &outgoing_transport_feedback_,
   1330        &outgoing_congestion_feedback_, &outgoing_loss_notification_);
   1331    RTC_RETURN_IF_ERROR(store_rtcp_status);
   1332  }
   1333 
   1334  // Store first and last timestamp events that might happen before the call is
   1335  // connected or after the call is disconnected. Typical examples are
   1336  // stream configurations and starting/stopping the log.
   1337  // TODO(terelius): Figure out if we actually need to find the first and last
   1338  // timestamp in the parser. It seems like this could be done by the caller.
   1339  first_timestamp_ = Timestamp::PlusInfinity();
   1340  last_timestamp_ = Timestamp::MinusInfinity();
   1341  StoreFirstAndLastTimestamp(alr_state_events());
   1342  StoreFirstAndLastTimestamp(route_change_events());
   1343  for (const auto& audio_stream : audio_playout_events()) {
   1344    // Audio playout events are grouped by SSRC.
   1345    StoreFirstAndLastTimestamp(audio_stream.second);
   1346  }
   1347  for (const auto& set_minimum_delay : neteq_set_minimum_delay_events()) {
   1348    // NetEq SetMinimumDelay grouped by SSRC.
   1349    StoreFirstAndLastTimestamp(set_minimum_delay.second);
   1350  }
   1351  StoreFirstAndLastTimestamp(audio_network_adaptation_events());
   1352  StoreFirstAndLastTimestamp(bwe_probe_cluster_created_events());
   1353  StoreFirstAndLastTimestamp(bwe_probe_failure_events());
   1354  StoreFirstAndLastTimestamp(bwe_probe_success_events());
   1355  StoreFirstAndLastTimestamp(bwe_delay_updates());
   1356  StoreFirstAndLastTimestamp(bwe_loss_updates());
   1357  for (const auto& frame_stream : decoded_frames()) {
   1358    StoreFirstAndLastTimestamp(frame_stream.second);
   1359  }
   1360  StoreFirstAndLastTimestamp(dtls_transport_states());
   1361  StoreFirstAndLastTimestamp(dtls_writable_states());
   1362  StoreFirstAndLastTimestamp(ice_candidate_pair_configs());
   1363  StoreFirstAndLastTimestamp(ice_candidate_pair_events());
   1364  for (const auto& rtp_stream : incoming_rtp_packets_by_ssrc()) {
   1365    StoreFirstAndLastTimestamp(rtp_stream.incoming_packets);
   1366  }
   1367  for (const auto& rtp_stream : outgoing_rtp_packets_by_ssrc()) {
   1368    StoreFirstAndLastTimestamp(rtp_stream.outgoing_packets);
   1369  }
   1370  StoreFirstAndLastTimestamp(incoming_rtcp_packets());
   1371  StoreFirstAndLastTimestamp(outgoing_rtcp_packets());
   1372  StoreFirstAndLastTimestamp(generic_packets_sent_);
   1373  StoreFirstAndLastTimestamp(generic_packets_received_);
   1374  StoreFirstAndLastTimestamp(remote_estimate_events_);
   1375 
   1376  // Stop events could be missing due to file size limits. If so, use the
   1377  // last event, or the next start timestamp if available.
   1378  // TODO(terelius): This could be improved. Instead of using the next start
   1379  // event, we could use the timestamp of the the last previous regular event.
   1380  auto start_iter = start_log_events().begin();
   1381  auto stop_iter = stop_log_events().begin();
   1382  int64_t start_us =
   1383      first_timestamp().us_or(std::numeric_limits<int64_t>::max());
   1384  int64_t next_start_us = std::numeric_limits<int64_t>::max();
   1385  int64_t stop_us = std::numeric_limits<int64_t>::max();
   1386  if (start_iter != start_log_events().end()) {
   1387    start_us = std::min(start_us, start_iter->log_time_us());
   1388    ++start_iter;
   1389    if (start_iter != start_log_events().end())
   1390      next_start_us = start_iter->log_time_us();
   1391  }
   1392  if (stop_iter != stop_log_events().end()) {
   1393    stop_us = stop_iter->log_time_us();
   1394  }
   1395  stop_us = std::min(stop_us, next_start_us);
   1396  if (stop_us == std::numeric_limits<int64_t>::max() &&
   1397      !last_timestamp().IsMinusInfinity()) {
   1398    stop_us = last_timestamp().us();
   1399  }
   1400  RTC_PARSE_CHECK_OR_RETURN_LE(start_us, stop_us);
   1401  first_log_segment_ = LogSegment(start_us, stop_us);
   1402 
   1403  if (first_timestamp_ > last_timestamp_) {
   1404    first_timestamp_ = last_timestamp_ = Timestamp::Zero();
   1405  }
   1406 
   1407  return status;
   1408 }
   1409 
   1410 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStreamInternal(
   1411    absl::string_view s) {
   1412  constexpr uint64_t kMaxEventSize = 10000000;  // Sanity check.
   1413  // Protobuf defines the message tag as
   1414  // (field_number << 3) | wire_type. In the legacy encoding, the field number
   1415  // is supposed to be 1 and the wire type for a length-delimited field is 2.
   1416  // In the new encoding we still expect the wire type to be 2, but the field
   1417  // number will be greater than 1.
   1418  constexpr uint64_t kExpectedV1Tag = (1 << 3) | 2;
   1419  bool success = false;
   1420 
   1421  // "Peek" at the first varint.
   1422  absl::string_view event_start = s;
   1423  uint64_t tag = 0;
   1424  std::tie(success, std::ignore) = DecodeVarInt(s, &tag);
   1425  if (!success) {
   1426    RTC_LOG(LS_WARNING) << "Failed to read varint from beginning of event log.";
   1427    RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
   1428                                         kIncompleteLogError);
   1429    return ParseStatus::Error("Failed to read field tag varint", __FILE__,
   1430                              __LINE__);
   1431  }
   1432  s = event_start;
   1433 
   1434  if (tag >> 1 == static_cast<uint64_t>(RtcEvent::Type::BeginV3Log)) {
   1435    return ParseStreamInternalV3(s);
   1436  }
   1437 
   1438  while (!s.empty()) {
   1439    // If not, "reset" event_start and read the field tag for the next event.
   1440    event_start = s;
   1441    std::tie(success, s) = DecodeVarInt(s, &tag);
   1442    if (!success) {
   1443      RTC_LOG(LS_WARNING)
   1444          << "Failed to read field tag from beginning of protobuf event.";
   1445      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
   1446                                           kIncompleteLogError);
   1447      return ParseStatus::Error("Failed to read field tag varint", __FILE__,
   1448                                __LINE__);
   1449    }
   1450 
   1451    constexpr uint64_t kWireTypeMask = 0x07;
   1452    const uint64_t wire_type = tag & kWireTypeMask;
   1453    if (wire_type != 2) {
   1454      RTC_LOG(LS_WARNING) << "Expected field tag with wire type 2 (length "
   1455                             "delimited message). Found wire type "
   1456                          << wire_type;
   1457      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
   1458                                           kIncompleteLogError);
   1459      RTC_PARSE_CHECK_OR_RETURN_EQ(wire_type, 2);
   1460    }
   1461 
   1462    // Read the length field.
   1463    uint64_t message_length = 0;
   1464    std::tie(success, s) = DecodeVarInt(s, &message_length);
   1465    if (!success) {
   1466      RTC_LOG(LS_WARNING) << "Missing message length after protobuf field tag.";
   1467      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
   1468                                           kIncompleteLogError);
   1469      return ParseStatus::Error("Failed to read message length varint",
   1470                                __FILE__, __LINE__);
   1471    }
   1472 
   1473    if (message_length > s.size()) {
   1474      RTC_LOG(LS_WARNING) << "Protobuf message length is larger than the "
   1475                             "remaining bytes in the proto.";
   1476      RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
   1477                                           kIncompleteLogError);
   1478      return ParseStatus::Error(
   1479          "Incomplete message: the length of the next message is larger than "
   1480          "the remaining bytes in the proto",
   1481          __FILE__, __LINE__);
   1482    }
   1483 
   1484    RTC_PARSE_CHECK_OR_RETURN_LE(message_length, kMaxEventSize);
   1485    // Skip forward to the start of the next event.
   1486    s = s.substr(message_length);
   1487    size_t total_event_size = event_start.size() - s.size();
   1488    RTC_CHECK_LE(total_event_size, event_start.size());
   1489 
   1490    if (tag == kExpectedV1Tag) {
   1491      // Parse the protobuf event from the buffer.
   1492      rtclog::EventStream event_stream;
   1493      if (!event_stream.ParseFromArray(event_start.data(), total_event_size)) {
   1494        RTC_LOG(LS_WARNING)
   1495            << "Failed to parse legacy-format protobuf message.";
   1496        RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
   1497                                             kIncompleteLogError);
   1498        RTC_PARSE_CHECK_OR_RETURN(false);
   1499      }
   1500 
   1501      RTC_PARSE_CHECK_OR_RETURN_EQ(event_stream.stream_size(), 1);
   1502      auto status = StoreParsedLegacyEvent(event_stream.stream(0));
   1503      RTC_RETURN_IF_ERROR(status);
   1504    } else {
   1505      // Parse the protobuf event from the buffer.
   1506      rtclog2::EventStream event_stream;
   1507      if (!event_stream.ParseFromArray(event_start.data(), total_event_size)) {
   1508        RTC_LOG(LS_WARNING) << "Failed to parse new-format protobuf message.";
   1509        RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
   1510                                             kIncompleteLogError);
   1511        RTC_PARSE_CHECK_OR_RETURN(false);
   1512      }
   1513      auto status = StoreParsedNewFormatEvent(event_stream);
   1514      RTC_RETURN_IF_ERROR(status);
   1515    }
   1516  }
   1517  return ParseStatus::Success();
   1518 }
   1519 
   1520 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStreamInternalV3(
   1521    absl::string_view s) {
   1522  constexpr uint64_t kMaxEventSize = 10000000;  // Sanity check.
   1523  bool expect_begin_log_event = true;
   1524  bool success = false;
   1525 
   1526  while (!s.empty()) {
   1527    // Read event type.
   1528    uint64_t event_tag = 0;
   1529    std::tie(success, s) = DecodeVarInt(s, &event_tag);
   1530    RTC_PARSE_CHECK_OR_RETURN_MESSAGE(success, "Failed to read event type.");
   1531    bool batched = event_tag & 1;
   1532    uint64_t event_type = event_tag >> 1;
   1533 
   1534    // Read event size
   1535    uint64_t event_size_bytes = 0;
   1536    std::tie(success, s) = DecodeVarInt(s, &event_size_bytes);
   1537    RTC_PARSE_CHECK_OR_RETURN_MESSAGE(success, "Failed to read event size.");
   1538    if (event_size_bytes > kMaxEventSize || event_size_bytes > s.size()) {
   1539      RTC_LOG(LS_WARNING) << "Event size is too large.";
   1540      RTC_PARSE_CHECK_OR_RETURN_LE(event_size_bytes, kMaxEventSize);
   1541      RTC_PARSE_CHECK_OR_RETURN_LE(event_size_bytes, s.size());
   1542    }
   1543 
   1544    // Read remaining event fields into a buffer.
   1545    absl::string_view event_fields = s.substr(0, event_size_bytes);
   1546    s = s.substr(event_size_bytes);
   1547 
   1548    if (expect_begin_log_event) {
   1549      RTC_PARSE_CHECK_OR_RETURN_EQ(
   1550          event_type, static_cast<uint32_t>(RtcEvent::Type::BeginV3Log));
   1551      expect_begin_log_event = false;
   1552    }
   1553 
   1554    switch (event_type) {
   1555      case static_cast<uint32_t>(RtcEvent::Type::BeginV3Log):
   1556        RtcEventBeginLog::Parse(event_fields, batched, start_log_events_);
   1557        break;
   1558      case static_cast<uint32_t>(RtcEvent::Type::EndV3Log):
   1559        RtcEventEndLog::Parse(event_fields, batched, stop_log_events_);
   1560        expect_begin_log_event = true;
   1561        break;
   1562      case static_cast<uint32_t>(RtcEvent::Type::AlrStateEvent):
   1563        RtcEventAlrState::Parse(event_fields, batched, alr_state_events_);
   1564        break;
   1565      case static_cast<uint32_t>(RtcEvent::Type::AudioPlayout):
   1566        RtcEventAudioPlayout::Parse(event_fields, batched,
   1567                                    audio_playout_events_);
   1568        break;
   1569      case static_cast<uint32_t>(RtcEvent::Type::BweUpdateDelayBased):
   1570        RtcEventBweUpdateDelayBased::Parse(event_fields, batched,
   1571                                           bwe_delay_updates_);
   1572        break;
   1573      case static_cast<uint32_t>(RtcEvent::Type::AudioNetworkAdaptation):
   1574        RtcEventAudioNetworkAdaptation::Parse(event_fields, batched,
   1575                                              audio_network_adaptation_events_);
   1576        break;
   1577      case static_cast<uint32_t>(RtcEvent::Type::AudioReceiveStreamConfig):
   1578        RtcEventAudioReceiveStreamConfig::Parse(event_fields, batched,
   1579                                                audio_recv_configs_);
   1580        break;
   1581      case static_cast<uint32_t>(RtcEvent::Type::AudioSendStreamConfig):
   1582        RtcEventAudioSendStreamConfig::Parse(event_fields, batched,
   1583                                             audio_send_configs_);
   1584        break;
   1585      case static_cast<uint32_t>(RtcEvent::Type::BweUpdateLossBased):
   1586        RtcEventBweUpdateLossBased::Parse(event_fields, batched,
   1587                                          bwe_loss_updates_);
   1588        break;
   1589      case static_cast<uint32_t>(RtcEvent::Type::DtlsTransportState):
   1590        RtcEventDtlsTransportState::Parse(event_fields, batched,
   1591                                          dtls_transport_states_);
   1592        break;
   1593      case static_cast<uint32_t>(RtcEvent::Type::DtlsWritableState):
   1594        RtcEventDtlsWritableState::Parse(event_fields, batched,
   1595                                         dtls_writable_states_);
   1596        break;
   1597      case static_cast<uint32_t>(RtcEvent::Type::FrameDecoded):
   1598        RtcEventFrameDecoded::Parse(event_fields, batched, decoded_frames_);
   1599        break;
   1600      case static_cast<uint32_t>(RtcEvent::Type::GenericPacketReceived):
   1601        RtcEventGenericPacketReceived::Parse(event_fields, batched,
   1602                                             generic_packets_received_);
   1603        break;
   1604      case static_cast<uint32_t>(RtcEvent::Type::GenericPacketSent):
   1605        RtcEventGenericPacketSent::Parse(event_fields, batched,
   1606                                         generic_packets_sent_);
   1607        break;
   1608      case static_cast<uint32_t>(RtcEvent::Type::IceCandidatePairConfig):
   1609        RtcEventIceCandidatePairConfig::Parse(event_fields, batched,
   1610                                              ice_candidate_pair_configs_);
   1611        break;
   1612      case static_cast<uint32_t>(RtcEvent::Type::IceCandidatePairEvent):
   1613        RtcEventIceCandidatePair::Parse(event_fields, batched,
   1614                                        ice_candidate_pair_events_);
   1615        break;
   1616      case static_cast<uint32_t>(RtcEvent::Type::ProbeClusterCreated):
   1617        RtcEventProbeClusterCreated::Parse(event_fields, batched,
   1618                                           bwe_probe_cluster_created_events_);
   1619        break;
   1620      case static_cast<uint32_t>(RtcEvent::Type::ProbeResultFailure):
   1621        RtcEventProbeResultFailure::Parse(event_fields, batched,
   1622                                          bwe_probe_failure_events_);
   1623        break;
   1624      case static_cast<uint32_t>(RtcEvent::Type::ProbeResultSuccess):
   1625        RtcEventProbeResultSuccess::Parse(event_fields, batched,
   1626                                          bwe_probe_success_events_);
   1627        break;
   1628      case static_cast<uint32_t>(RtcEvent::Type::RemoteEstimateEvent):
   1629        RtcEventRemoteEstimate::Parse(event_fields, batched,
   1630                                      remote_estimate_events_);
   1631        break;
   1632      case static_cast<uint32_t>(RtcEvent::Type::RouteChangeEvent):
   1633        RtcEventRouteChange::Parse(event_fields, batched, route_change_events_);
   1634        break;
   1635      case static_cast<uint32_t>(RtcEvent::Type::RtcpPacketIncoming):
   1636        RtcEventRtcpPacketIncoming::Parse(event_fields, batched,
   1637                                          incoming_rtcp_packets_);
   1638        break;
   1639      case static_cast<uint32_t>(RtcEvent::Type::RtcpPacketOutgoing):
   1640        RtcEventRtcpPacketOutgoing::Parse(event_fields, batched,
   1641                                          outgoing_rtcp_packets_);
   1642        break;
   1643      case static_cast<uint32_t>(RtcEvent::Type::RtpPacketIncoming):
   1644        RtcEventRtpPacketIncoming::Parse(event_fields, batched,
   1645                                         incoming_rtp_packets_map_);
   1646        break;
   1647      case static_cast<uint32_t>(RtcEvent::Type::RtpPacketOutgoing):
   1648        RtcEventRtpPacketOutgoing::Parse(event_fields, batched,
   1649                                         outgoing_rtp_packets_map_);
   1650        break;
   1651      case static_cast<uint32_t>(RtcEvent::Type::VideoReceiveStreamConfig):
   1652        RtcEventVideoReceiveStreamConfig::Parse(event_fields, batched,
   1653                                                video_recv_configs_);
   1654        break;
   1655      case static_cast<uint32_t>(RtcEvent::Type::VideoSendStreamConfig):
   1656        RtcEventVideoSendStreamConfig::Parse(event_fields, batched,
   1657                                             video_send_configs_);
   1658        break;
   1659    }
   1660  }
   1661 
   1662  return ParseStatus::Success();
   1663 }
   1664 
   1665 template <typename T>
   1666 void ParsedRtcEventLog::StoreFirstAndLastTimestamp(const std::vector<T>& v) {
   1667  if (v.empty())
   1668    return;
   1669  first_timestamp_ = std::min(first_timestamp_, v.front().log_time());
   1670  last_timestamp_ = std::max(last_timestamp_, v.back().log_time());
   1671 }
   1672 
   1673 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedLegacyEvent(
   1674    const rtclog::Event& event) {
   1675  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   1676  switch (event.type()) {
   1677    case rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT: {
   1678      auto config = GetVideoReceiveConfig(event);
   1679      if (!config.ok())
   1680        return config.status();
   1681 
   1682      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1683      int64_t timestamp_us = event.timestamp_us();
   1684      video_recv_configs_.emplace_back(Timestamp::Micros(timestamp_us),
   1685                                       config.value());
   1686      incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
   1687          RtpHeaderExtensionMap(config.value().rtp_extensions);
   1688      incoming_rtp_extensions_maps_[config.value().rtx_ssrc] =
   1689          RtpHeaderExtensionMap(config.value().rtp_extensions);
   1690      break;
   1691    }
   1692    case rtclog::Event::VIDEO_SENDER_CONFIG_EVENT: {
   1693      auto config = GetVideoSendConfig(event);
   1694      if (!config.ok())
   1695        return config.status();
   1696 
   1697      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1698      int64_t timestamp_us = event.timestamp_us();
   1699      video_send_configs_.emplace_back(Timestamp::Micros(timestamp_us),
   1700                                       config.value());
   1701      outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
   1702          RtpHeaderExtensionMap(config.value().rtp_extensions);
   1703      outgoing_rtp_extensions_maps_[config.value().rtx_ssrc] =
   1704          RtpHeaderExtensionMap(config.value().rtp_extensions);
   1705      break;
   1706    }
   1707    case rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT: {
   1708      auto config = GetAudioReceiveConfig(event);
   1709      if (!config.ok())
   1710        return config.status();
   1711 
   1712      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1713      int64_t timestamp_us = event.timestamp_us();
   1714      audio_recv_configs_.emplace_back(Timestamp::Micros(timestamp_us),
   1715                                       config.value());
   1716      incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
   1717          RtpHeaderExtensionMap(config.value().rtp_extensions);
   1718      break;
   1719    }
   1720    case rtclog::Event::AUDIO_SENDER_CONFIG_EVENT: {
   1721      auto config = GetAudioSendConfig(event);
   1722      if (!config.ok())
   1723        return config.status();
   1724      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1725      int64_t timestamp_us = event.timestamp_us();
   1726      audio_send_configs_.emplace_back(Timestamp::Micros(timestamp_us),
   1727                                       config.value());
   1728      outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
   1729          RtpHeaderExtensionMap(config.value().rtp_extensions);
   1730      break;
   1731    }
   1732    case rtclog::Event::RTP_EVENT: {
   1733      RTC_PARSE_CHECK_OR_RETURN(event.has_rtp_packet());
   1734      const rtclog::RtpPacket& rtp_packet = event.rtp_packet();
   1735      RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_header());
   1736      RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_incoming());
   1737      RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_packet_length());
   1738      size_t total_length = rtp_packet.packet_length();
   1739 
   1740      // Use RtpPacketReceived instead of more generic RtpPacket because former
   1741      // has a buildin convertion to RTPHeader.
   1742      RtpPacketReceived rtp_header;
   1743      RTC_PARSE_CHECK_OR_RETURN(
   1744          rtp_header.Parse(CopyOnWriteBuffer(rtp_packet.header())));
   1745 
   1746      if (const RtpHeaderExtensionMap* extension_map = GetRtpHeaderExtensionMap(
   1747              rtp_packet.incoming(), rtp_header.Ssrc())) {
   1748        rtp_header.IdentifyExtensions(*extension_map);
   1749      }
   1750 
   1751      RTPHeader parsed_header;
   1752      rtp_header.GetHeader(&parsed_header);
   1753 
   1754      // Since we give the parser only a header, there is no way for it to know
   1755      // the padding length. The best solution would be to log the padding
   1756      // length in RTC event log. In absence of it, we assume the RTP packet to
   1757      // contain only padding, if the padding bit is set.
   1758      // TODO(webrtc:9730): Use a generic way to obtain padding length.
   1759      if (rtp_header.has_padding())
   1760        parsed_header.paddingLength = total_length - rtp_header.size();
   1761 
   1762      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1763      int64_t timestamp_us = event.timestamp_us();
   1764      if (rtp_packet.incoming()) {
   1765        incoming_rtp_packets_map_[parsed_header.ssrc].push_back(
   1766            LoggedRtpPacketIncoming(Timestamp::Micros(timestamp_us),
   1767                                    parsed_header, rtp_header.size(),
   1768                                    total_length));
   1769      } else {
   1770        outgoing_rtp_packets_map_[parsed_header.ssrc].push_back(
   1771            LoggedRtpPacketOutgoing(Timestamp::Micros(timestamp_us),
   1772                                    parsed_header, rtp_header.size(),
   1773                                    total_length));
   1774      }
   1775      break;
   1776    }
   1777    case rtclog::Event::RTCP_EVENT: {
   1778      PacketDirection direction;
   1779      std::vector<uint8_t> packet;
   1780      auto status = GetRtcpPacket(event, &direction, &packet);
   1781      RTC_RETURN_IF_ERROR(status);
   1782      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1783      int64_t timestamp_us = event.timestamp_us();
   1784      if (direction == kIncomingPacket) {
   1785        // Currently incoming RTCP packets are logged twice, both for audio and
   1786        // video. Only act on one of them. Compare against the previous parsed
   1787        // incoming RTCP packet.
   1788        if (packet == last_incoming_rtcp_packet_)
   1789          break;
   1790        incoming_rtcp_packets_.push_back(
   1791            LoggedRtcpPacketIncoming(Timestamp::Micros(timestamp_us), packet));
   1792        last_incoming_rtcp_packet_ = packet;
   1793      } else {
   1794        outgoing_rtcp_packets_.push_back(
   1795            LoggedRtcpPacketOutgoing(Timestamp::Micros(timestamp_us), packet));
   1796      }
   1797      break;
   1798    }
   1799    case rtclog::Event::LOG_START: {
   1800      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1801      int64_t timestamp_us = event.timestamp_us();
   1802      start_log_events_.push_back(
   1803          LoggedStartEvent(Timestamp::Micros(timestamp_us)));
   1804      break;
   1805    }
   1806    case rtclog::Event::LOG_END: {
   1807      RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   1808      int64_t timestamp_us = event.timestamp_us();
   1809      stop_log_events_.push_back(
   1810          LoggedStopEvent(Timestamp::Micros(timestamp_us)));
   1811      break;
   1812    }
   1813    case rtclog::Event::AUDIO_PLAYOUT_EVENT: {
   1814      auto status_or_value = GetAudioPlayout(event);
   1815      RTC_RETURN_IF_ERROR(status_or_value.status());
   1816      LoggedAudioPlayoutEvent playout_event = status_or_value.value();
   1817      audio_playout_events_[playout_event.ssrc].push_back(playout_event);
   1818      break;
   1819    }
   1820    case rtclog::Event::LOSS_BASED_BWE_UPDATE: {
   1821      auto status_or_value = GetLossBasedBweUpdate(event);
   1822      RTC_RETURN_IF_ERROR(status_or_value.status());
   1823      bwe_loss_updates_.push_back(status_or_value.value());
   1824      break;
   1825    }
   1826    case rtclog::Event::DELAY_BASED_BWE_UPDATE: {
   1827      auto status_or_value = GetDelayBasedBweUpdate(event);
   1828      RTC_RETURN_IF_ERROR(status_or_value.status());
   1829      bwe_delay_updates_.push_back(status_or_value.value());
   1830      break;
   1831    }
   1832    case rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT: {
   1833      auto status_or_value = GetAudioNetworkAdaptation(event);
   1834      RTC_RETURN_IF_ERROR(status_or_value.status());
   1835      audio_network_adaptation_events_.push_back(status_or_value.value());
   1836      break;
   1837    }
   1838    case rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT: {
   1839      auto status_or_value = GetBweProbeClusterCreated(event);
   1840      RTC_RETURN_IF_ERROR(status_or_value.status());
   1841      bwe_probe_cluster_created_events_.push_back(status_or_value.value());
   1842      break;
   1843    }
   1844    case rtclog::Event::BWE_PROBE_RESULT_EVENT: {
   1845      // Probe successes and failures are currently stored in the same proto
   1846      // message, we are moving towards separate messages. Probe results
   1847      // therefore need special treatment in the parser.
   1848      RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
   1849      RTC_PARSE_CHECK_OR_RETURN(event.probe_result().has_result());
   1850      if (event.probe_result().result() == rtclog::BweProbeResult::SUCCESS) {
   1851        auto status_or_value = GetBweProbeSuccess(event);
   1852        RTC_RETURN_IF_ERROR(status_or_value.status());
   1853        bwe_probe_success_events_.push_back(status_or_value.value());
   1854      } else {
   1855        auto status_or_value = GetBweProbeFailure(event);
   1856        RTC_RETURN_IF_ERROR(status_or_value.status());
   1857        bwe_probe_failure_events_.push_back(status_or_value.value());
   1858      }
   1859      break;
   1860    }
   1861    case rtclog::Event::ALR_STATE_EVENT: {
   1862      auto status_or_value = GetAlrState(event);
   1863      RTC_RETURN_IF_ERROR(status_or_value.status());
   1864      alr_state_events_.push_back(status_or_value.value());
   1865      break;
   1866    }
   1867    case rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG: {
   1868      auto status_or_value = GetIceCandidatePairConfig(event);
   1869      RTC_RETURN_IF_ERROR(status_or_value.status());
   1870      ice_candidate_pair_configs_.push_back(status_or_value.value());
   1871      break;
   1872    }
   1873    case rtclog::Event::ICE_CANDIDATE_PAIR_EVENT: {
   1874      auto status_or_value = GetIceCandidatePairEvent(event);
   1875      RTC_RETURN_IF_ERROR(status_or_value.status());
   1876      ice_candidate_pair_events_.push_back(status_or_value.value());
   1877      break;
   1878    }
   1879    case rtclog::Event::REMOTE_ESTIMATE: {
   1880      auto status_or_value = GetRemoteEstimateEvent(event);
   1881      RTC_RETURN_IF_ERROR(status_or_value.status());
   1882      remote_estimate_events_.push_back(status_or_value.value());
   1883      break;
   1884    }
   1885    case rtclog::Event::UNKNOWN_EVENT: {
   1886      break;
   1887    }
   1888  }
   1889  return ParseStatus::Success();
   1890 }
   1891 
   1892 const RtpHeaderExtensionMap* ParsedRtcEventLog::GetRtpHeaderExtensionMap(
   1893    bool incoming,
   1894    uint32_t ssrc) {
   1895  auto& extensions_maps =
   1896      incoming ? incoming_rtp_extensions_maps_ : outgoing_rtp_extensions_maps_;
   1897  auto it = extensions_maps.find(ssrc);
   1898  if (it != extensions_maps.end()) {
   1899    return &(it->second);
   1900  }
   1901  if (parse_unconfigured_header_extensions_ ==
   1902      UnconfiguredHeaderExtensions::kAttemptWebrtcDefaultConfig) {
   1903    RTC_DLOG(LS_WARNING) << "Using default header extension map for SSRC "
   1904                         << ssrc;
   1905    extensions_maps.insert(std::make_pair(ssrc, default_extension_map_));
   1906    return &default_extension_map_;
   1907  }
   1908  RTC_DLOG(LS_WARNING) << "Not parsing header extensions for SSRC " << ssrc
   1909                       << ". No header extension map found.";
   1910  return nullptr;
   1911 }
   1912 
   1913 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::GetRtcpPacket(
   1914    const rtclog::Event& event,
   1915    PacketDirection* incoming,
   1916    std::vector<uint8_t>* packet) const {
   1917  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   1918  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::RTCP_EVENT);
   1919  RTC_PARSE_CHECK_OR_RETURN(event.has_rtcp_packet());
   1920  const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet();
   1921  // Get direction of packet.
   1922  RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_incoming());
   1923  if (incoming != nullptr) {
   1924    *incoming = rtcp_packet.incoming() ? kIncomingPacket : kOutgoingPacket;
   1925  }
   1926  // Get packet contents.
   1927  RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_packet_data());
   1928  if (packet != nullptr) {
   1929    packet->resize(rtcp_packet.packet_data().size());
   1930    memcpy(packet->data(), rtcp_packet.packet_data().data(),
   1931           rtcp_packet.packet_data().size());
   1932  }
   1933  return ParseStatus::Success();
   1934 }
   1935 
   1936 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
   1937 ParsedRtcEventLog::GetVideoReceiveConfig(const rtclog::Event& event) const {
   1938  rtclog::StreamConfig config;
   1939  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   1940  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   1941                               rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
   1942  RTC_PARSE_CHECK_OR_RETURN(event.has_video_receiver_config());
   1943  const rtclog::VideoReceiveConfig& receiver_config =
   1944      event.video_receiver_config();
   1945  // Get SSRCs.
   1946  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remote_ssrc());
   1947  config.remote_ssrc = receiver_config.remote_ssrc();
   1948  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_local_ssrc());
   1949  config.local_ssrc = receiver_config.local_ssrc();
   1950  config.rtx_ssrc = 0;
   1951  // Get RTCP settings.
   1952  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_rtcp_mode());
   1953  config.rtcp_mode = GetRuntimeRtcpMode(receiver_config.rtcp_mode());
   1954  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remb());
   1955  config.remb = receiver_config.remb();
   1956 
   1957  // Get RTX map.
   1958  std::map<uint32_t, const rtclog::RtxConfig> rtx_map;
   1959  for (int i = 0; i < receiver_config.rtx_map_size(); i++) {
   1960    const rtclog::RtxMap& map = receiver_config.rtx_map(i);
   1961    RTC_PARSE_CHECK_OR_RETURN(map.has_payload_type());
   1962    RTC_PARSE_CHECK_OR_RETURN(map.has_config());
   1963    RTC_PARSE_CHECK_OR_RETURN(map.config().has_rtx_ssrc());
   1964    RTC_PARSE_CHECK_OR_RETURN(map.config().has_rtx_payload_type());
   1965    rtx_map.insert(std::make_pair(map.payload_type(), map.config()));
   1966  }
   1967 
   1968  // Get header extensions.
   1969  auto status = GetHeaderExtensions(&config.rtp_extensions,
   1970                                    receiver_config.header_extensions());
   1971  RTC_RETURN_IF_ERROR(status);
   1972 
   1973  // Get decoders.
   1974  config.codecs.clear();
   1975  for (int i = 0; i < receiver_config.decoders_size(); i++) {
   1976    RTC_PARSE_CHECK_OR_RETURN(receiver_config.decoders(i).has_name());
   1977    RTC_PARSE_CHECK_OR_RETURN(receiver_config.decoders(i).has_payload_type());
   1978    int rtx_payload_type = 0;
   1979    auto rtx_it = rtx_map.find(receiver_config.decoders(i).payload_type());
   1980    if (rtx_it != rtx_map.end()) {
   1981      rtx_payload_type = rtx_it->second.rtx_payload_type();
   1982      if (config.rtx_ssrc != 0 &&
   1983          config.rtx_ssrc != rtx_it->second.rtx_ssrc()) {
   1984        RTC_LOG(LS_WARNING)
   1985            << "RtcEventLog protobuf contained different SSRCs for "
   1986               "different received RTX payload types. Will only use "
   1987               "rtx_ssrc = "
   1988            << config.rtx_ssrc << ".";
   1989      } else {
   1990        config.rtx_ssrc = rtx_it->second.rtx_ssrc();
   1991      }
   1992    }
   1993    config.codecs.emplace_back(receiver_config.decoders(i).name(),
   1994                               receiver_config.decoders(i).payload_type(),
   1995                               rtx_payload_type);
   1996  }
   1997  return config;
   1998 }
   1999 
   2000 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
   2001 ParsedRtcEventLog::GetVideoSendConfig(const rtclog::Event& event) const {
   2002  rtclog::StreamConfig config;
   2003  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2004  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2005                               rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
   2006  RTC_PARSE_CHECK_OR_RETURN(event.has_video_sender_config());
   2007  const rtclog::VideoSendConfig& sender_config = event.video_sender_config();
   2008 
   2009  // Get SSRCs.
   2010  // VideoSendStreamConfig no longer stores multiple SSRCs. If you are
   2011  // analyzing a very old log, try building the parser from the same
   2012  // WebRTC version.
   2013  RTC_PARSE_CHECK_OR_RETURN_EQ(sender_config.ssrcs_size(), 1);
   2014  config.local_ssrc = sender_config.ssrcs(0);
   2015  RTC_PARSE_CHECK_OR_RETURN_LE(sender_config.rtx_ssrcs_size(), 1);
   2016  if (sender_config.rtx_ssrcs_size() == 1) {
   2017    config.rtx_ssrc = sender_config.rtx_ssrcs(0);
   2018  }
   2019 
   2020  // Get header extensions.
   2021  auto status = GetHeaderExtensions(&config.rtp_extensions,
   2022                                    sender_config.header_extensions());
   2023  RTC_RETURN_IF_ERROR(status);
   2024 
   2025  // Get the codec.
   2026  RTC_PARSE_CHECK_OR_RETURN(sender_config.has_encoder());
   2027  RTC_PARSE_CHECK_OR_RETURN(sender_config.encoder().has_name());
   2028  RTC_PARSE_CHECK_OR_RETURN(sender_config.encoder().has_payload_type());
   2029  config.codecs.emplace_back(
   2030      sender_config.encoder().name(), sender_config.encoder().payload_type(),
   2031      sender_config.has_rtx_payload_type() ? sender_config.rtx_payload_type()
   2032                                           : 0);
   2033  return config;
   2034 }
   2035 
   2036 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
   2037 ParsedRtcEventLog::GetAudioReceiveConfig(const rtclog::Event& event) const {
   2038  rtclog::StreamConfig config;
   2039  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2040  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2041                               rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT);
   2042  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_receiver_config());
   2043  const rtclog::AudioReceiveConfig& receiver_config =
   2044      event.audio_receiver_config();
   2045  // Get SSRCs.
   2046  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remote_ssrc());
   2047  config.remote_ssrc = receiver_config.remote_ssrc();
   2048  RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_local_ssrc());
   2049  config.local_ssrc = receiver_config.local_ssrc();
   2050  // Get header extensions.
   2051  auto status = GetHeaderExtensions(&config.rtp_extensions,
   2052                                    receiver_config.header_extensions());
   2053  RTC_RETURN_IF_ERROR(status);
   2054 
   2055  return config;
   2056 }
   2057 
   2058 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
   2059 ParsedRtcEventLog::GetAudioSendConfig(const rtclog::Event& event) const {
   2060  rtclog::StreamConfig config;
   2061  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2062  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2063                               rtclog::Event::AUDIO_SENDER_CONFIG_EVENT);
   2064  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_sender_config());
   2065  const rtclog::AudioSendConfig& sender_config = event.audio_sender_config();
   2066  // Get SSRCs.
   2067  RTC_PARSE_CHECK_OR_RETURN(sender_config.has_ssrc());
   2068  config.local_ssrc = sender_config.ssrc();
   2069  // Get header extensions.
   2070  auto status = GetHeaderExtensions(&config.rtp_extensions,
   2071                                    sender_config.header_extensions());
   2072  RTC_RETURN_IF_ERROR(status);
   2073 
   2074  return config;
   2075 }
   2076 
   2077 ParsedRtcEventLog::ParseStatusOr<LoggedAudioPlayoutEvent>
   2078 ParsedRtcEventLog::GetAudioPlayout(const rtclog::Event& event) const {
   2079  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2080  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2081                               rtclog::Event::AUDIO_PLAYOUT_EVENT);
   2082  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_playout_event());
   2083  const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event();
   2084  LoggedAudioPlayoutEvent res;
   2085  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2086  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2087  RTC_PARSE_CHECK_OR_RETURN(playout_event.has_local_ssrc());
   2088  res.ssrc = playout_event.local_ssrc();
   2089  return res;
   2090 }
   2091 
   2092 ParsedRtcEventLog::ParseStatusOr<LoggedBweLossBasedUpdate>
   2093 ParsedRtcEventLog::GetLossBasedBweUpdate(const rtclog::Event& event) const {
   2094  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2095  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2096                               rtclog::Event::LOSS_BASED_BWE_UPDATE);
   2097  RTC_PARSE_CHECK_OR_RETURN(event.has_loss_based_bwe_update());
   2098  const rtclog::LossBasedBweUpdate& loss_event = event.loss_based_bwe_update();
   2099 
   2100  LoggedBweLossBasedUpdate bwe_update;
   2101  RTC_CHECK(event.has_timestamp_us());
   2102  bwe_update.timestamp = Timestamp::Micros(event.timestamp_us());
   2103  RTC_PARSE_CHECK_OR_RETURN(loss_event.has_bitrate_bps());
   2104  bwe_update.bitrate_bps = loss_event.bitrate_bps();
   2105  RTC_PARSE_CHECK_OR_RETURN(loss_event.has_fraction_loss());
   2106  bwe_update.fraction_lost = loss_event.fraction_loss();
   2107  RTC_PARSE_CHECK_OR_RETURN(loss_event.has_total_packets());
   2108  bwe_update.expected_packets = loss_event.total_packets();
   2109  return bwe_update;
   2110 }
   2111 
   2112 ParsedRtcEventLog::ParseStatusOr<LoggedBweDelayBasedUpdate>
   2113 ParsedRtcEventLog::GetDelayBasedBweUpdate(const rtclog::Event& event) const {
   2114  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2115  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2116                               rtclog::Event::DELAY_BASED_BWE_UPDATE);
   2117  RTC_PARSE_CHECK_OR_RETURN(event.has_delay_based_bwe_update());
   2118  const rtclog::DelayBasedBweUpdate& delay_event =
   2119      event.delay_based_bwe_update();
   2120 
   2121  LoggedBweDelayBasedUpdate res;
   2122  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2123  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2124  RTC_PARSE_CHECK_OR_RETURN(delay_event.has_bitrate_bps());
   2125  res.bitrate_bps = delay_event.bitrate_bps();
   2126  RTC_PARSE_CHECK_OR_RETURN(delay_event.has_detector_state());
   2127  res.detector_state = GetRuntimeDetectorState(delay_event.detector_state());
   2128  return res;
   2129 }
   2130 
   2131 ParsedRtcEventLog::ParseStatusOr<LoggedAudioNetworkAdaptationEvent>
   2132 ParsedRtcEventLog::GetAudioNetworkAdaptation(const rtclog::Event& event) const {
   2133  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2134  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2135                               rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
   2136  RTC_PARSE_CHECK_OR_RETURN(event.has_audio_network_adaptation());
   2137  const rtclog::AudioNetworkAdaptation& ana_event =
   2138      event.audio_network_adaptation();
   2139 
   2140  LoggedAudioNetworkAdaptationEvent res;
   2141  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2142  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2143  if (ana_event.has_bitrate_bps())
   2144    res.config.bitrate_bps = ana_event.bitrate_bps();
   2145  if (ana_event.has_enable_fec())
   2146    res.config.enable_fec = ana_event.enable_fec();
   2147  if (ana_event.has_enable_dtx())
   2148    res.config.enable_dtx = ana_event.enable_dtx();
   2149  if (ana_event.has_frame_length_ms())
   2150    res.config.frame_length_ms = ana_event.frame_length_ms();
   2151  if (ana_event.has_num_channels())
   2152    res.config.num_channels = ana_event.num_channels();
   2153  if (ana_event.has_uplink_packet_loss_fraction())
   2154    res.config.uplink_packet_loss_fraction =
   2155        ana_event.uplink_packet_loss_fraction();
   2156  return res;
   2157 }
   2158 
   2159 ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeClusterCreatedEvent>
   2160 ParsedRtcEventLog::GetBweProbeClusterCreated(const rtclog::Event& event) const {
   2161  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2162  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2163                               rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
   2164  RTC_PARSE_CHECK_OR_RETURN(event.has_probe_cluster());
   2165  const rtclog::BweProbeCluster& pcc_event = event.probe_cluster();
   2166  LoggedBweProbeClusterCreatedEvent res;
   2167  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2168  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2169  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_id());
   2170  res.id = pcc_event.id();
   2171  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_bitrate_bps());
   2172  res.bitrate_bps = pcc_event.bitrate_bps();
   2173  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_min_packets());
   2174  res.min_packets = pcc_event.min_packets();
   2175  RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_min_bytes());
   2176  res.min_bytes = pcc_event.min_bytes();
   2177  return res;
   2178 }
   2179 
   2180 ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeFailureEvent>
   2181 ParsedRtcEventLog::GetBweProbeFailure(const rtclog::Event& event) const {
   2182  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2183  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2184                               rtclog::Event::BWE_PROBE_RESULT_EVENT);
   2185  RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
   2186  const rtclog::BweProbeResult& pr_event = event.probe_result();
   2187  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
   2188  RTC_PARSE_CHECK_OR_RETURN_NE(pr_event.result(),
   2189                               rtclog::BweProbeResult::SUCCESS);
   2190 
   2191  LoggedBweProbeFailureEvent res;
   2192  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2193  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2194  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_id());
   2195  res.id = pr_event.id();
   2196  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
   2197  if (pr_event.result() ==
   2198      rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL) {
   2199    res.failure_reason = ProbeFailureReason::kInvalidSendReceiveInterval;
   2200  } else if (pr_event.result() ==
   2201             rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO) {
   2202    res.failure_reason = ProbeFailureReason::kInvalidSendReceiveRatio;
   2203  } else if (pr_event.result() == rtclog::BweProbeResult::TIMEOUT) {
   2204    res.failure_reason = ProbeFailureReason::kTimeout;
   2205  } else {
   2206    RTC_DCHECK_NOTREACHED();
   2207  }
   2208  RTC_PARSE_CHECK_OR_RETURN(!pr_event.has_bitrate_bps());
   2209 
   2210  return res;
   2211 }
   2212 
   2213 ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeSuccessEvent>
   2214 ParsedRtcEventLog::GetBweProbeSuccess(const rtclog::Event& event) const {
   2215  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2216  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
   2217                               rtclog::Event::BWE_PROBE_RESULT_EVENT);
   2218  RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
   2219  const rtclog::BweProbeResult& pr_event = event.probe_result();
   2220  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
   2221  RTC_PARSE_CHECK_OR_RETURN_EQ(pr_event.result(),
   2222                               rtclog::BweProbeResult::SUCCESS);
   2223 
   2224  LoggedBweProbeSuccessEvent res;
   2225  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2226  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2227  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_id());
   2228  res.id = pr_event.id();
   2229  RTC_PARSE_CHECK_OR_RETURN(pr_event.has_bitrate_bps());
   2230  res.bitrate_bps = pr_event.bitrate_bps();
   2231 
   2232  return res;
   2233 }
   2234 
   2235 ParsedRtcEventLog::ParseStatusOr<LoggedAlrStateEvent>
   2236 ParsedRtcEventLog::GetAlrState(const rtclog::Event& event) const {
   2237  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2238  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::ALR_STATE_EVENT);
   2239  RTC_PARSE_CHECK_OR_RETURN(event.has_alr_state());
   2240  const rtclog::AlrState& alr_event = event.alr_state();
   2241  LoggedAlrStateEvent res;
   2242  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2243  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2244  RTC_PARSE_CHECK_OR_RETURN(alr_event.has_in_alr());
   2245  res.in_alr = alr_event.in_alr();
   2246 
   2247  return res;
   2248 }
   2249 
   2250 ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairConfig>
   2251 ParsedRtcEventLog::GetIceCandidatePairConfig(
   2252    const rtclog::Event& rtc_event) const {
   2253  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_type());
   2254  RTC_PARSE_CHECK_OR_RETURN_EQ(rtc_event.type(),
   2255                               rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
   2256  LoggedIceCandidatePairConfig res;
   2257  const rtclog::IceCandidatePairConfig& config =
   2258      rtc_event.ice_candidate_pair_config();
   2259  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_timestamp_us());
   2260  res.timestamp = Timestamp::Micros(rtc_event.timestamp_us());
   2261  RTC_PARSE_CHECK_OR_RETURN(config.has_config_type());
   2262  res.type = GetRuntimeIceCandidatePairConfigType(config.config_type());
   2263  RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_id());
   2264  res.candidate_pair_id = config.candidate_pair_id();
   2265  RTC_PARSE_CHECK_OR_RETURN(config.has_local_candidate_type());
   2266  RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType(
   2267      config.local_candidate_type(), res.local_candidate_type));
   2268  RTC_PARSE_CHECK_OR_RETURN(config.has_local_relay_protocol());
   2269  res.local_relay_protocol =
   2270      GetRuntimeIceCandidatePairProtocol(config.local_relay_protocol());
   2271  RTC_PARSE_CHECK_OR_RETURN(config.has_local_network_type());
   2272  res.local_network_type =
   2273      GetRuntimeIceCandidateNetworkType(config.local_network_type());
   2274  RTC_PARSE_CHECK_OR_RETURN(config.has_local_address_family());
   2275  res.local_address_family =
   2276      GetRuntimeIceCandidatePairAddressFamily(config.local_address_family());
   2277  RTC_PARSE_CHECK_OR_RETURN(config.has_remote_candidate_type());
   2278  RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType(
   2279      config.remote_candidate_type(), res.remote_candidate_type));
   2280  RTC_PARSE_CHECK_OR_RETURN(config.has_remote_address_family());
   2281  res.remote_address_family =
   2282      GetRuntimeIceCandidatePairAddressFamily(config.remote_address_family());
   2283  RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_protocol());
   2284  res.candidate_pair_protocol =
   2285      GetRuntimeIceCandidatePairProtocol(config.candidate_pair_protocol());
   2286  return res;
   2287 }
   2288 
   2289 ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairEvent>
   2290 ParsedRtcEventLog::GetIceCandidatePairEvent(
   2291    const rtclog::Event& rtc_event) const {
   2292  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_type());
   2293  RTC_PARSE_CHECK_OR_RETURN_EQ(rtc_event.type(),
   2294                               rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
   2295  LoggedIceCandidatePairEvent res;
   2296  const rtclog::IceCandidatePairEvent& event =
   2297      rtc_event.ice_candidate_pair_event();
   2298  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_timestamp_us());
   2299  res.timestamp = Timestamp::Micros(rtc_event.timestamp_us());
   2300  RTC_PARSE_CHECK_OR_RETURN(event.has_event_type());
   2301  res.type = GetRuntimeIceCandidatePairEventType(event.event_type());
   2302  RTC_PARSE_CHECK_OR_RETURN(event.has_candidate_pair_id());
   2303  res.candidate_pair_id = event.candidate_pair_id();
   2304  // transaction_id is not supported by rtclog::Event
   2305  res.transaction_id = 0;
   2306  return res;
   2307 }
   2308 
   2309 ParsedRtcEventLog::ParseStatusOr<LoggedRemoteEstimateEvent>
   2310 ParsedRtcEventLog::GetRemoteEstimateEvent(const rtclog::Event& event) const {
   2311  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
   2312  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::REMOTE_ESTIMATE);
   2313  LoggedRemoteEstimateEvent res;
   2314  const rtclog::RemoteEstimate& remote_estimate_event = event.remote_estimate();
   2315  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
   2316  res.timestamp = Timestamp::Micros(event.timestamp_us());
   2317  if (remote_estimate_event.has_link_capacity_lower_kbps())
   2318    res.link_capacity_lower = DataRate::KilobitsPerSec(
   2319        remote_estimate_event.link_capacity_lower_kbps());
   2320  if (remote_estimate_event.has_link_capacity_upper_kbps())
   2321    res.link_capacity_upper = DataRate::KilobitsPerSec(
   2322        remote_estimate_event.link_capacity_upper_kbps());
   2323  return res;
   2324 }
   2325 
   2326 // Returns the MediaType for registered SSRCs. Search from the end to use last
   2327 // registered types first.
   2328 ParsedRtcEventLog::MediaType ParsedRtcEventLog::GetMediaType(
   2329    uint32_t ssrc,
   2330    PacketDirection direction) const {
   2331  if (direction == kIncomingPacket) {
   2332    if (std::find(incoming_video_ssrcs_.begin(), incoming_video_ssrcs_.end(),
   2333                  ssrc) != incoming_video_ssrcs_.end()) {
   2334      return MediaType::VIDEO;
   2335    }
   2336    if (std::find(incoming_audio_ssrcs_.begin(), incoming_audio_ssrcs_.end(),
   2337                  ssrc) != incoming_audio_ssrcs_.end()) {
   2338      return MediaType::AUDIO;
   2339    }
   2340  } else {
   2341    if (std::find(outgoing_video_ssrcs_.begin(), outgoing_video_ssrcs_.end(),
   2342                  ssrc) != outgoing_video_ssrcs_.end()) {
   2343      return MediaType::VIDEO;
   2344    }
   2345    if (std::find(outgoing_audio_ssrcs_.begin(), outgoing_audio_ssrcs_.end(),
   2346                  ssrc) != outgoing_audio_ssrcs_.end()) {
   2347      return MediaType::AUDIO;
   2348    }
   2349  }
   2350  return MediaType::ANY;
   2351 }
   2352 
   2353 std::vector<InferredRouteChangeEvent> ParsedRtcEventLog::GetRouteChanges()
   2354    const {
   2355  std::vector<InferredRouteChangeEvent> route_changes;
   2356  for (auto& candidate : ice_candidate_pair_configs()) {
   2357    if (candidate.type == IceCandidatePairConfigType::kSelected) {
   2358      InferredRouteChangeEvent route;
   2359      route.route_id = candidate.candidate_pair_id;
   2360      route.log_time = Timestamp::Millis(candidate.log_time_ms());
   2361 
   2362      route.send_overhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead;
   2363      if (candidate.remote_address_family ==
   2364          IceCandidatePairAddressFamily::kIpv6)
   2365        route.send_overhead += kIpv6Overhead - kIpv4Overhead;
   2366      if (candidate.remote_candidate_type != IceCandidateType::kHost)
   2367        route.send_overhead += kStunOverhead;
   2368      route.return_overhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead;
   2369      if (candidate.remote_address_family ==
   2370          IceCandidatePairAddressFamily::kIpv6)
   2371        route.return_overhead += kIpv6Overhead - kIpv4Overhead;
   2372      if (candidate.remote_candidate_type != IceCandidateType::kHost)
   2373        route.return_overhead += kStunOverhead;
   2374      route_changes.push_back(route);
   2375    }
   2376  }
   2377  return route_changes;
   2378 }
   2379 
   2380 std::vector<LoggedPacketInfo> ParsedRtcEventLog::GetPacketInfos(
   2381    PacketDirection direction) const {
   2382  std::map<uint32_t, MediaStreamInfo> streams;
   2383  if (direction == PacketDirection::kIncomingPacket) {
   2384    AddRecvStreamInfos(&streams, audio_recv_configs(), LoggedMediaType::kAudio);
   2385    AddRecvStreamInfos(&streams, video_recv_configs(), LoggedMediaType::kVideo);
   2386  } else if (direction == PacketDirection::kOutgoingPacket) {
   2387    AddSendStreamInfos(&streams, audio_send_configs(), LoggedMediaType::kAudio);
   2388    AddSendStreamInfos(&streams, video_send_configs(), LoggedMediaType::kVideo);
   2389  }
   2390 
   2391  std::vector<OverheadChangeEvent> overheads =
   2392      GetOverheadChangingEvents(GetRouteChanges(), direction);
   2393  auto overhead_iter = overheads.begin();
   2394  std::vector<LoggedPacketInfo> packets;
   2395  std::map</*unwrapped transport sequence number*/ int64_t,
   2396           /*index into packets*/ size_t>
   2397      twcc_indices;
   2398  RtpSequenceNumberUnwrapper transport_seq_num_unwrapper;
   2399 
   2400  class PerSSRCInfo {
   2401   public:
   2402    void AddPacketIndex(uint16_t rtp_sequence_number, size_t index) {
   2403      packet_indices_[rtp_seq_num_unwrapper_.Unwrap(rtp_sequence_number)] =
   2404          index;
   2405    }
   2406    std::optional<size_t> FindPacketIndex(uint16_t rtp_sequence_number) {
   2407      auto it = packet_indices_.find(
   2408          rtp_seq_num_unwrapper_.Unwrap(rtp_sequence_number));
   2409      if (it == packet_indices_.end()) {
   2410        return std::nullopt;
   2411      }
   2412      return it->second;
   2413    }
   2414 
   2415   private:
   2416    RtpSequenceNumberUnwrapper rtp_seq_num_unwrapper_;
   2417    std::map</*unwrapped rtp sequence number*/ int64_t,
   2418             /*index into packets*/ size_t>
   2419        packet_indices_;
   2420  };
   2421  std::map</*ssrc*/ uint32_t, PerSSRCInfo> ccfb_indices;
   2422 
   2423  uint16_t current_overhead = kDefaultOverhead;
   2424  Timestamp last_log_time = Timestamp::Zero();
   2425 
   2426  auto advance_time = [&](Timestamp new_log_time) {
   2427    if (overhead_iter != overheads.end() &&
   2428        new_log_time >= overhead_iter->timestamp) {
   2429      current_overhead = overhead_iter->overhead;
   2430      ++overhead_iter;
   2431    }
   2432    // If we have a large time delta, it can be caused by a gap in logging,
   2433    // therefore we don't want to match up sequence numbers as we might have had
   2434    // a wraparound.
   2435    if (new_log_time - last_log_time > TimeDelta::Seconds(30)) {
   2436      transport_seq_num_unwrapper.Reset();
   2437      twcc_indices.clear();
   2438      ccfb_indices.clear();
   2439    }
   2440    RTC_DCHECK_GE(new_log_time, last_log_time);
   2441    last_log_time = new_log_time;
   2442  };
   2443 
   2444  auto rtp_handler = [&](const LoggedRtpPacket& rtp) {
   2445    advance_time(rtp.log_time());
   2446    MediaStreamInfo* stream = &streams[rtp.header.ssrc];
   2447    Timestamp capture_time = Timestamp::MinusInfinity();
   2448    if (!stream->rtx) {
   2449      // RTX copy the timestamp of the retransmitted packets. This means that
   2450      // RTX streams don't have a unique clock offset and frequency, so
   2451      // the RTP timstamps can't be unwrapped.
   2452 
   2453      // Add an offset to avoid `capture_ticks` to become negative in the case
   2454      // of reordering.
   2455      constexpr int64_t kStartingCaptureTimeTicks = 90 * 48 * 10000;
   2456      int64_t capture_ticks =
   2457          kStartingCaptureTimeTicks +
   2458          stream->unwrap_capture_ticks.Unwrap(rtp.header.timestamp);
   2459      // TODO(srte): Use logged sample rate when it is added to the format.
   2460      capture_time = Timestamp::Seconds(
   2461          capture_ticks /
   2462          (stream->media_type == LoggedMediaType::kAudio ? 48000.0 : 90000.0));
   2463    }
   2464    LoggedPacketInfo logged(rtp, stream->media_type, stream->rtx, capture_time);
   2465    logged.overhead = current_overhead;
   2466    if (logged.has_transport_seq_no) {
   2467      logged.log_feedback_time = Timestamp::PlusInfinity();
   2468      int64_t unwrapped_seq_num =
   2469          transport_seq_num_unwrapper.Unwrap(logged.transport_seq_no);
   2470      if (twcc_indices.find(unwrapped_seq_num) != twcc_indices.end()) {
   2471        Timestamp prev_log_packet_time =
   2472            packets[twcc_indices[unwrapped_seq_num]].log_packet_time;
   2473        RTC_LOG(LS_WARNING)
   2474            << "Repeated sent packet sequence number: " << unwrapped_seq_num
   2475            << " Packet time:" << prev_log_packet_time.seconds() << "s vs "
   2476            << logged.log_packet_time.seconds()
   2477            << "s at:" << rtp.log_time_ms() / 1000;
   2478      }
   2479      twcc_indices[unwrapped_seq_num] = packets.size();
   2480    } else {
   2481      ccfb_indices[rtp.header.ssrc].AddPacketIndex(rtp.header.sequenceNumber,
   2482                                                   packets.size());
   2483    }
   2484    packets.push_back(logged);
   2485  };
   2486 
   2487  Timestamp twcc_feedback_base_time = Timestamp::MinusInfinity();
   2488  Timestamp twcc_last_feedback_base_time = Timestamp::MinusInfinity();
   2489 
   2490  auto twcc_feedback_handler =
   2491      [&](const LoggedRtcpPacketTransportFeedback& logged_rtcp) {
   2492        auto log_feedback_time = logged_rtcp.log_time();
   2493        advance_time(log_feedback_time);
   2494        const auto& feedback = logged_rtcp.transport_feedback;
   2495        // Add timestamp deltas to a local time base selected on first packet
   2496        // arrival. This won't be the true time base, but makes it easier to
   2497        // manually inspect time stamps.
   2498        if (!twcc_last_feedback_base_time.IsFinite()) {
   2499          twcc_feedback_base_time = log_feedback_time;
   2500        } else {
   2501          twcc_feedback_base_time +=
   2502              feedback.GetBaseDelta(twcc_last_feedback_base_time);
   2503        }
   2504        twcc_last_feedback_base_time = feedback.BaseTime();
   2505 
   2506        std::vector<LoggedPacketInfo*> packet_feedbacks;
   2507        packet_feedbacks.reserve(feedback.GetPacketStatusCount());
   2508        std::vector<int64_t> unknown_seq_nums;
   2509        feedback.ForAllPackets([&](uint16_t sequence_number,
   2510                                   TimeDelta delta_since_base) {
   2511          int64_t unwrapped_seq_num =
   2512              transport_seq_num_unwrapper.Unwrap(sequence_number);
   2513          auto it = twcc_indices.find(unwrapped_seq_num);
   2514          if (it == twcc_indices.end()) {
   2515            unknown_seq_nums.push_back(unwrapped_seq_num);
   2516            return;
   2517          }
   2518          LoggedPacketInfo* sent = &packets[it->second];
   2519          if (log_feedback_time - sent->log_packet_time >
   2520              TimeDelta::Seconds(60)) {
   2521            RTC_LOG(LS_WARNING)
   2522                << "Received very late feedback, possibly due to wraparound.";
   2523            return;
   2524          }
   2525          if (delta_since_base.IsFinite()) {
   2526            if (sent->reported_recv_time.IsInfinite()) {
   2527              sent->reported_recv_time =
   2528                  twcc_feedback_base_time + delta_since_base;
   2529              sent->log_feedback_time = log_feedback_time;
   2530            }
   2531          } else {
   2532            if (sent->reported_recv_time.IsInfinite() &&
   2533                sent->log_feedback_time.IsInfinite()) {
   2534              sent->reported_recv_time = Timestamp::PlusInfinity();
   2535              sent->log_feedback_time = log_feedback_time;
   2536            }
   2537          }
   2538          packet_feedbacks.push_back(sent);
   2539        });
   2540        if (!unknown_seq_nums.empty()) {
   2541          RTC_LOG(LS_WARNING)
   2542              << "Received feedback for unknown packets: "
   2543              << unknown_seq_nums.front() << " - " << unknown_seq_nums.back();
   2544        }
   2545        if (packet_feedbacks.empty())
   2546          return;
   2547        LoggedPacketInfo* last = packet_feedbacks.back();
   2548        last->last_in_feedback = true;
   2549        for (LoggedPacketInfo* fb : packet_feedbacks) {
   2550          if (direction == PacketDirection::kOutgoingPacket) {
   2551            if (last->reported_recv_time.IsFinite() &&
   2552                fb->reported_recv_time.IsFinite()) {
   2553              fb->feedback_hold_duration =
   2554                  last->reported_recv_time - fb->reported_recv_time;
   2555            }
   2556          } else {
   2557            fb->feedback_hold_duration =
   2558                log_feedback_time - fb->log_packet_time;
   2559          }
   2560        }
   2561      };
   2562 
   2563  Timestamp ccfb_feedback_offset = Timestamp::MinusInfinity();
   2564  std::optional<uint32_t> last_feedback_compact_ntp_time_;
   2565  auto ccfb_feedback_handler =
   2566      [&](const LoggedRtcpCongestionControlFeedback& logged_rtcp) {
   2567        Timestamp log_feedback_time = logged_rtcp.log_time();
   2568        advance_time(log_feedback_time);
   2569        const rtcp::CongestionControlFeedback& feedback =
   2570            logged_rtcp.congestion_feedback;
   2571 
   2572        if (ccfb_feedback_offset.IsInfinite()) {
   2573          ccfb_feedback_offset = log_feedback_time;
   2574        }
   2575        TimeDelta feedback_delta =
   2576            last_feedback_compact_ntp_time_.has_value()
   2577                ? CompactNtpIntervalToTimeDelta(
   2578                      feedback.report_timestamp_compact_ntp() -
   2579                      *last_feedback_compact_ntp_time_)
   2580                : TimeDelta::Zero();
   2581        last_feedback_compact_ntp_time_ =
   2582            feedback.report_timestamp_compact_ntp();
   2583        if (feedback_delta < TimeDelta::Zero()) {
   2584          RTC_LOG(LS_WARNING)
   2585              << "Unexpected feedback ntp time delta " << feedback_delta << ".";
   2586          ccfb_feedback_offset = log_feedback_time;
   2587        } else {
   2588          ccfb_feedback_offset += feedback_delta;
   2589        }
   2590        for (const rtcp::CongestionControlFeedback::PacketInfo& packet :
   2591             feedback.packets()) {
   2592          std::optional<size_t> packets_index =
   2593              ccfb_indices[packet.ssrc].FindPacketIndex(packet.sequence_number);
   2594          if (!packets_index.has_value()) {
   2595            RTC_LOG(LS_WARNING)
   2596                << " Got feedback for unknown packet, ssrc: " << packet.ssrc
   2597                << " rtp seqno:" << packet.sequence_number;
   2598            continue;
   2599          }
   2600          LoggedPacketInfo* sent = &packets[*packets_index];
   2601          RTC_DCHECK_EQ(packet.ssrc, sent->ssrc);
   2602          RTC_DCHECK_EQ(packet.sequence_number, sent->stream_seq_no);
   2603          if (log_feedback_time - sent->log_packet_time >
   2604              TimeDelta::Seconds(60)) {
   2605            RTC_LOG(LS_WARNING)
   2606                << "Received very late feedback, possibly due to wraparound.";
   2607            return;
   2608          }
   2609          if (packet.arrival_time_offset.IsFinite()) {
   2610            if (sent->reported_recv_time.IsInfinite()) {
   2611              sent->log_feedback_time = log_feedback_time;
   2612              sent->feedback_hold_duration = packet.arrival_time_offset;
   2613              sent->reported_recv_time =
   2614                  ccfb_feedback_offset - packet.arrival_time_offset;
   2615            }
   2616          } else {
   2617            if (sent->log_feedback_time.IsInfinite()) {
   2618              sent->log_feedback_time = log_feedback_time;
   2619              sent->reported_recv_time = Timestamp::PlusInfinity();
   2620            }
   2621          }
   2622        }
   2623      };
   2624 
   2625  RtcEventProcessor process;
   2626  for (const auto& rtp_packets : rtp_packets_by_ssrc(direction)) {
   2627    process.AddEvents(rtp_packets.packet_view, rtp_handler, direction);
   2628  }
   2629  if (direction == PacketDirection::kOutgoingPacket) {
   2630    process.AddEvents(incoming_transport_feedback_, twcc_feedback_handler,
   2631                      PacketDirection::kIncomingPacket);
   2632    process.AddEvents(incoming_congestion_feedback_, ccfb_feedback_handler,
   2633                      PacketDirection::kIncomingPacket);
   2634  } else {
   2635    process.AddEvents(outgoing_transport_feedback_, twcc_feedback_handler,
   2636                      PacketDirection::kOutgoingPacket);
   2637    process.AddEvents(outgoing_congestion_feedback_, ccfb_feedback_handler,
   2638                      PacketDirection::kOutgoingPacket);
   2639  }
   2640  process.ProcessEventsInOrder();
   2641  return packets;
   2642 }
   2643 
   2644 std::vector<LoggedIceCandidatePairConfig> ParsedRtcEventLog::GetIceCandidates()
   2645    const {
   2646  std::vector<LoggedIceCandidatePairConfig> candidates;
   2647  std::set<uint32_t> added;
   2648  for (auto& candidate : ice_candidate_pair_configs()) {
   2649    if (added.find(candidate.candidate_pair_id) == added.end()) {
   2650      candidates.push_back(candidate);
   2651      added.insert(candidate.candidate_pair_id);
   2652    }
   2653  }
   2654  return candidates;
   2655 }
   2656 
   2657 std::vector<LoggedIceEvent> ParsedRtcEventLog::GetIceEvents() const {
   2658  using CheckType = IceCandidatePairEventType;
   2659  using ConfigType = IceCandidatePairConfigType;
   2660  using Combined = LoggedIceEventType;
   2661  std::map<CheckType, Combined> check_map(
   2662      {{CheckType::kCheckSent, Combined::kCheckSent},
   2663       {CheckType::kCheckReceived, Combined::kCheckReceived},
   2664       {CheckType::kCheckResponseSent, Combined::kCheckResponseSent},
   2665       {CheckType::kCheckResponseReceived, Combined::kCheckResponseReceived}});
   2666  std::map<ConfigType, Combined> config_map(
   2667      {{ConfigType::kAdded, Combined::kAdded},
   2668       {ConfigType::kUpdated, Combined::kUpdated},
   2669       {ConfigType::kDestroyed, Combined::kDestroyed},
   2670       {ConfigType::kSelected, Combined::kSelected}});
   2671  std::vector<LoggedIceEvent> log_events;
   2672  auto handle_check = [&](const LoggedIceCandidatePairEvent& check) {
   2673    log_events.push_back(
   2674        LoggedIceEvent{.candidate_pair_id = check.candidate_pair_id,
   2675                       .log_time = Timestamp::Millis(check.log_time_ms()),
   2676                       .event_type = check_map[check.type]});
   2677  };
   2678  auto handle_config = [&](const LoggedIceCandidatePairConfig& conf) {
   2679    log_events.push_back(
   2680        LoggedIceEvent{.candidate_pair_id = conf.candidate_pair_id,
   2681                       .log_time = Timestamp::Millis(conf.log_time_ms()),
   2682                       .event_type = config_map[conf.type]});
   2683  };
   2684  RtcEventProcessor process;
   2685  process.AddEvents(ice_candidate_pair_events(), handle_check);
   2686  process.AddEvents(ice_candidate_pair_configs(), handle_config);
   2687  process.ProcessEventsInOrder();
   2688  return log_events;
   2689 }
   2690 
   2691 std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
   2692    const ParsedRtcEventLog& parsed_log) {
   2693  std::vector<MatchedSendArrivalTimes> rtp_rtcp_matched;
   2694  for (auto& packet :
   2695       parsed_log.GetPacketInfos(PacketDirection::kOutgoingPacket)) {
   2696    if (packet.log_feedback_time.IsFinite()) {
   2697      rtp_rtcp_matched.emplace_back(packet.log_feedback_time.ms(),
   2698                                    packet.log_packet_time.ms(),
   2699                                    packet.reported_recv_time.ms_or(
   2700                                        MatchedSendArrivalTimes::kNotReceived),
   2701                                    packet.size);
   2702    }
   2703  }
   2704  return rtp_rtcp_matched;
   2705 }
   2706 
   2707 // Helper functions for new format start here
   2708 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedNewFormatEvent(
   2709    const rtclog2::EventStream& stream) {
   2710  RTC_DCHECK_EQ(stream.stream_size(), 0);  // No legacy format event.
   2711 
   2712  RTC_DCHECK_EQ(
   2713      stream.incoming_rtp_packets_size() + stream.outgoing_rtp_packets_size() +
   2714          stream.incoming_rtcp_packets_size() +
   2715          stream.outgoing_rtcp_packets_size() +
   2716          stream.audio_playout_events_size() + stream.begin_log_events_size() +
   2717          stream.end_log_events_size() + stream.loss_based_bwe_updates_size() +
   2718          stream.delay_based_bwe_updates_size() +
   2719          stream.dtls_transport_state_events_size() +
   2720          stream.dtls_writable_states_size() +
   2721          stream.audio_network_adaptations_size() +
   2722          stream.probe_clusters_size() + stream.probe_success_size() +
   2723          stream.probe_failure_size() + stream.alr_states_size() +
   2724          stream.route_changes_size() + stream.remote_estimates_size() +
   2725          stream.ice_candidate_configs_size() +
   2726          stream.ice_candidate_events_size() +
   2727          stream.audio_recv_stream_configs_size() +
   2728          stream.audio_send_stream_configs_size() +
   2729          stream.video_recv_stream_configs_size() +
   2730          stream.video_send_stream_configs_size() +
   2731          stream.generic_packets_sent_size() +
   2732          stream.generic_packets_received_size() +
   2733          stream.generic_acks_received_size() +
   2734          stream.frame_decoded_events_size() +
   2735          stream.neteq_set_minimum_delay_size(),
   2736      1u);
   2737 
   2738  if (stream.incoming_rtp_packets_size() == 1) {
   2739    return StoreIncomingRtpPackets(stream.incoming_rtp_packets(0));
   2740  } else if (stream.outgoing_rtp_packets_size() == 1) {
   2741    return StoreOutgoingRtpPackets(stream.outgoing_rtp_packets(0));
   2742  } else if (stream.incoming_rtcp_packets_size() == 1) {
   2743    return StoreIncomingRtcpPackets(stream.incoming_rtcp_packets(0));
   2744  } else if (stream.outgoing_rtcp_packets_size() == 1) {
   2745    return StoreOutgoingRtcpPackets(stream.outgoing_rtcp_packets(0));
   2746  } else if (stream.audio_playout_events_size() == 1) {
   2747    return StoreAudioPlayoutEvent(stream.audio_playout_events(0));
   2748  } else if (stream.begin_log_events_size() == 1) {
   2749    return StoreStartEvent(stream.begin_log_events(0));
   2750  } else if (stream.end_log_events_size() == 1) {
   2751    return StoreStopEvent(stream.end_log_events(0));
   2752  } else if (stream.loss_based_bwe_updates_size() == 1) {
   2753    return StoreBweLossBasedUpdate(stream.loss_based_bwe_updates(0));
   2754  } else if (stream.delay_based_bwe_updates_size() == 1) {
   2755    return StoreBweDelayBasedUpdate(stream.delay_based_bwe_updates(0));
   2756  } else if (stream.dtls_transport_state_events_size() == 1) {
   2757    return StoreDtlsTransportState(stream.dtls_transport_state_events(0));
   2758  } else if (stream.dtls_writable_states_size() == 1) {
   2759    return StoreDtlsWritableState(stream.dtls_writable_states(0));
   2760  } else if (stream.audio_network_adaptations_size() == 1) {
   2761    return StoreAudioNetworkAdaptationEvent(
   2762        stream.audio_network_adaptations(0));
   2763  } else if (stream.probe_clusters_size() == 1) {
   2764    return StoreBweProbeClusterCreated(stream.probe_clusters(0));
   2765  } else if (stream.probe_success_size() == 1) {
   2766    return StoreBweProbeSuccessEvent(stream.probe_success(0));
   2767  } else if (stream.probe_failure_size() == 1) {
   2768    return StoreBweProbeFailureEvent(stream.probe_failure(0));
   2769  } else if (stream.alr_states_size() == 1) {
   2770    return StoreAlrStateEvent(stream.alr_states(0));
   2771  } else if (stream.route_changes_size() == 1) {
   2772    return StoreRouteChangeEvent(stream.route_changes(0));
   2773  } else if (stream.remote_estimates_size() == 1) {
   2774    return StoreRemoteEstimateEvent(stream.remote_estimates(0));
   2775  } else if (stream.ice_candidate_configs_size() == 1) {
   2776    return StoreIceCandidatePairConfig(stream.ice_candidate_configs(0));
   2777  } else if (stream.ice_candidate_events_size() == 1) {
   2778    return StoreIceCandidateEvent(stream.ice_candidate_events(0));
   2779  } else if (stream.audio_recv_stream_configs_size() == 1) {
   2780    return StoreAudioRecvConfig(stream.audio_recv_stream_configs(0));
   2781  } else if (stream.audio_send_stream_configs_size() == 1) {
   2782    return StoreAudioSendConfig(stream.audio_send_stream_configs(0));
   2783  } else if (stream.video_recv_stream_configs_size() == 1) {
   2784    return StoreVideoRecvConfig(stream.video_recv_stream_configs(0));
   2785  } else if (stream.video_send_stream_configs_size() == 1) {
   2786    return StoreVideoSendConfig(stream.video_send_stream_configs(0));
   2787  } else if (stream.generic_packets_received_size() == 1) {
   2788    return StoreGenericPacketReceivedEvent(stream.generic_packets_received(0));
   2789  } else if (stream.generic_packets_sent_size() == 1) {
   2790    return StoreGenericPacketSentEvent(stream.generic_packets_sent(0));
   2791  } else if (stream.frame_decoded_events_size() == 1) {
   2792    return StoreFrameDecodedEvents(stream.frame_decoded_events(0));
   2793  } else if (stream.neteq_set_minimum_delay_size() == 1) {
   2794    return StoreNetEqSetMinimumDelay(stream.neteq_set_minimum_delay(0));
   2795  } else {
   2796    RTC_DCHECK_NOTREACHED();
   2797    return ParseStatus::Success();
   2798  }
   2799 }
   2800 
   2801 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAlrStateEvent(
   2802    const rtclog2::AlrState& proto) {
   2803  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   2804  RTC_PARSE_CHECK_OR_RETURN(proto.has_in_alr());
   2805  LoggedAlrStateEvent alr_event;
   2806  alr_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
   2807  alr_event.in_alr = proto.in_alr();
   2808 
   2809  alr_state_events_.push_back(alr_event);
   2810  // TODO(terelius): Should we delta encode this event type?
   2811  return ParseStatus::Success();
   2812 }
   2813 
   2814 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreRouteChangeEvent(
   2815    const rtclog2::RouteChange& proto) {
   2816  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   2817  RTC_PARSE_CHECK_OR_RETURN(proto.has_connected());
   2818  RTC_PARSE_CHECK_OR_RETURN(proto.has_overhead());
   2819  LoggedRouteChangeEvent route_event;
   2820  route_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
   2821  route_event.connected = proto.connected();
   2822  route_event.overhead = proto.overhead();
   2823 
   2824  route_change_events_.push_back(route_event);
   2825  // TODO(terelius): Should we delta encode this event type?
   2826  return ParseStatus::Success();
   2827 }
   2828 
   2829 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreRemoteEstimateEvent(
   2830    const rtclog2::RemoteEstimates& proto) {
   2831  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   2832  // Base event
   2833  LoggedRemoteEstimateEvent base_event;
   2834  base_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
   2835 
   2836  std::optional<uint64_t> base_link_capacity_lower_kbps;
   2837  if (proto.has_link_capacity_lower_kbps()) {
   2838    base_link_capacity_lower_kbps = proto.link_capacity_lower_kbps();
   2839    base_event.link_capacity_lower =
   2840        DataRate::KilobitsPerSec(proto.link_capacity_lower_kbps());
   2841  }
   2842 
   2843  std::optional<uint64_t> base_link_capacity_upper_kbps;
   2844  if (proto.has_link_capacity_upper_kbps()) {
   2845    base_link_capacity_upper_kbps = proto.link_capacity_upper_kbps();
   2846    base_event.link_capacity_upper =
   2847        DataRate::KilobitsPerSec(proto.link_capacity_upper_kbps());
   2848  }
   2849 
   2850  remote_estimate_events_.push_back(base_event);
   2851 
   2852  const size_t number_of_deltas =
   2853      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   2854  if (number_of_deltas == 0) {
   2855    return ParseStatus::Success();
   2856  }
   2857 
   2858  // timestamp_ms
   2859  auto timestamp_ms_values =
   2860      DecodeDeltas(proto.timestamp_ms_deltas(),
   2861                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   2862  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   2863 
   2864  // link_capacity_lower_kbps
   2865  auto link_capacity_lower_kbps_values =
   2866      DecodeDeltas(proto.link_capacity_lower_kbps_deltas(),
   2867                   base_link_capacity_lower_kbps, number_of_deltas);
   2868  RTC_PARSE_CHECK_OR_RETURN_EQ(link_capacity_lower_kbps_values.size(),
   2869                               number_of_deltas);
   2870 
   2871  // link_capacity_upper_kbps
   2872  auto link_capacity_upper_kbps_values =
   2873      DecodeDeltas(proto.link_capacity_upper_kbps_deltas(),
   2874                   base_link_capacity_upper_kbps, number_of_deltas);
   2875  RTC_PARSE_CHECK_OR_RETURN_EQ(link_capacity_upper_kbps_values.size(),
   2876                               number_of_deltas);
   2877 
   2878  // Populate events from decoded deltas
   2879  for (size_t i = 0; i < number_of_deltas; ++i) {
   2880    LoggedRemoteEstimateEvent event;
   2881    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
   2882    event.timestamp = Timestamp::Millis(*timestamp_ms_values[i]);
   2883    if (link_capacity_lower_kbps_values[i])
   2884      event.link_capacity_lower =
   2885          DataRate::KilobitsPerSec(*link_capacity_lower_kbps_values[i]);
   2886    if (link_capacity_upper_kbps_values[i])
   2887      event.link_capacity_upper =
   2888          DataRate::KilobitsPerSec(*link_capacity_upper_kbps_values[i]);
   2889    remote_estimate_events_.push_back(event);
   2890  }
   2891  return ParseStatus::Success();
   2892 }
   2893 
   2894 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioPlayoutEvent(
   2895    const rtclog2::AudioPlayoutEvents& proto) {
   2896  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   2897  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
   2898 
   2899  // Base event
   2900  audio_playout_events_[proto.local_ssrc()].emplace_back(
   2901      Timestamp::Millis(proto.timestamp_ms()), proto.local_ssrc());
   2902 
   2903  const size_t number_of_deltas =
   2904      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   2905  if (number_of_deltas == 0) {
   2906    return ParseStatus::Success();
   2907  }
   2908 
   2909  // timestamp_ms
   2910  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   2911      DecodeDeltas(proto.timestamp_ms_deltas(),
   2912                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   2913  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   2914 
   2915  // local_ssrc
   2916  std::vector<std::optional<uint64_t>> local_ssrc_values = DecodeDeltas(
   2917      proto.local_ssrc_deltas(), proto.local_ssrc(), number_of_deltas);
   2918  RTC_PARSE_CHECK_OR_RETURN_EQ(local_ssrc_values.size(), number_of_deltas);
   2919 
   2920  // Populate events from decoded deltas
   2921  for (size_t i = 0; i < number_of_deltas; ++i) {
   2922    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
   2923    RTC_PARSE_CHECK_OR_RETURN(local_ssrc_values[i].has_value());
   2924    RTC_PARSE_CHECK_OR_RETURN_LE(local_ssrc_values[i].value(),
   2925                                 std::numeric_limits<uint32_t>::max());
   2926 
   2927    int64_t timestamp_ms;
   2928    RTC_PARSE_CHECK_OR_RETURN(
   2929        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   2930 
   2931    const uint32_t local_ssrc =
   2932        static_cast<uint32_t>(local_ssrc_values[i].value());
   2933    audio_playout_events_[local_ssrc].emplace_back(
   2934        Timestamp::Millis(timestamp_ms), local_ssrc);
   2935  }
   2936  return ParseStatus::Success();
   2937 }
   2938 
   2939 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreNetEqSetMinimumDelay(
   2940    const rtclog2::NetEqSetMinimumDelay& proto) {
   2941  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   2942  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
   2943  RTC_PARSE_CHECK_OR_RETURN(proto.has_minimum_delay_ms());
   2944 
   2945  // Base event
   2946  neteq_set_minimum_delay_events_[proto.remote_ssrc()].emplace_back(
   2947      Timestamp::Millis(proto.timestamp_ms()), proto.remote_ssrc(),
   2948      static_cast<int>(proto.minimum_delay_ms()));
   2949 
   2950  const size_t number_of_deltas =
   2951      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   2952  if (number_of_deltas == 0) {
   2953    return ParseStatus::Success();
   2954  }
   2955 
   2956  // timestamp_ms
   2957  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   2958      DecodeDeltas(proto.timestamp_ms_deltas(),
   2959                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   2960  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   2961 
   2962  // remote_ssrc
   2963  std::vector<std::optional<uint64_t>> remote_ssrc_values = DecodeDeltas(
   2964      proto.remote_ssrc_deltas(), proto.remote_ssrc(), number_of_deltas);
   2965  RTC_PARSE_CHECK_OR_RETURN_EQ(remote_ssrc_values.size(), number_of_deltas);
   2966 
   2967  // minimum_delay_ms
   2968  std::vector<std::optional<uint64_t>> minimum_delay_ms_values =
   2969      DecodeDeltas(proto.minimum_delay_ms_deltas(),
   2970                   ToUnsigned(proto.minimum_delay_ms()), number_of_deltas);
   2971  RTC_PARSE_CHECK_OR_RETURN_EQ(minimum_delay_ms_values.size(),
   2972                               number_of_deltas);
   2973 
   2974  // Populate events from decoded deltas
   2975  for (size_t i = 0; i < number_of_deltas; ++i) {
   2976    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
   2977    RTC_PARSE_CHECK_OR_RETURN(remote_ssrc_values[i].has_value());
   2978    RTC_PARSE_CHECK_OR_RETURN_LE(remote_ssrc_values[i].value(),
   2979                                 std::numeric_limits<uint32_t>::max());
   2980    RTC_PARSE_CHECK_OR_RETURN(minimum_delay_ms_values[i].has_value());
   2981 
   2982    int64_t timestamp_ms;
   2983    RTC_PARSE_CHECK_OR_RETURN(
   2984        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   2985 
   2986    const uint32_t remote_ssrc =
   2987        static_cast<uint32_t>(remote_ssrc_values[i].value());
   2988    int minimum_delay_ms;
   2989    RTC_PARSE_CHECK_OR_RETURN(
   2990        ToSigned(minimum_delay_ms_values[i].value(), &minimum_delay_ms));
   2991    neteq_set_minimum_delay_events_[remote_ssrc].emplace_back(
   2992        Timestamp::Millis(timestamp_ms), remote_ssrc, minimum_delay_ms);
   2993  }
   2994 
   2995  return ParseStatus::Success();
   2996 }
   2997 
   2998 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIncomingRtpPackets(
   2999    const rtclog2::IncomingRtpPackets& proto) {
   3000  return StoreRtpPackets(proto, &incoming_rtp_packets_map_);
   3001 }
   3002 
   3003 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreOutgoingRtpPackets(
   3004    const rtclog2::OutgoingRtpPackets& proto) {
   3005  return StoreRtpPackets(proto, &outgoing_rtp_packets_map_);
   3006 }
   3007 
   3008 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIncomingRtcpPackets(
   3009    const rtclog2::IncomingRtcpPackets& proto) {
   3010  return StoreRtcpPackets(proto, &incoming_rtcp_packets_,
   3011                          /*remove_duplicates=*/true);
   3012 }
   3013 
   3014 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreOutgoingRtcpPackets(
   3015    const rtclog2::OutgoingRtcpPackets& proto) {
   3016  return StoreRtcpPackets(proto, &outgoing_rtcp_packets_,
   3017                          /*remove_duplicates=*/false);
   3018 }
   3019 
   3020 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreStartEvent(
   3021    const rtclog2::BeginLogEvent& proto) {
   3022  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3023  RTC_PARSE_CHECK_OR_RETURN(proto.has_version());
   3024  RTC_PARSE_CHECK_OR_RETURN(proto.has_utc_time_ms());
   3025  RTC_PARSE_CHECK_OR_RETURN_EQ(proto.version(), 2);
   3026  LoggedStartEvent start_event(Timestamp::Millis(proto.timestamp_ms()),
   3027                               Timestamp::Millis(proto.utc_time_ms()));
   3028 
   3029  start_log_events_.push_back(start_event);
   3030  return ParseStatus::Success();
   3031 }
   3032 
   3033 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreStopEvent(
   3034    const rtclog2::EndLogEvent& proto) {
   3035  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3036  LoggedStopEvent stop_event(Timestamp::Millis(proto.timestamp_ms()));
   3037 
   3038  stop_log_events_.push_back(stop_event);
   3039  return ParseStatus::Success();
   3040 }
   3041 
   3042 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweLossBasedUpdate(
   3043    const rtclog2::LossBasedBweUpdates& proto) {
   3044  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3045  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
   3046  RTC_PARSE_CHECK_OR_RETURN(proto.has_fraction_loss());
   3047  RTC_PARSE_CHECK_OR_RETURN(proto.has_total_packets());
   3048 
   3049  // Base event
   3050  bwe_loss_updates_.emplace_back(Timestamp::Millis(proto.timestamp_ms()),
   3051                                 proto.bitrate_bps(), proto.fraction_loss(),
   3052                                 proto.total_packets());
   3053 
   3054  const size_t number_of_deltas =
   3055      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   3056  if (number_of_deltas == 0) {
   3057    return ParseStatus::Success();
   3058  }
   3059 
   3060  // timestamp_ms
   3061  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   3062      DecodeDeltas(proto.timestamp_ms_deltas(),
   3063                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   3064  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   3065 
   3066  // bitrate_bps
   3067  std::vector<std::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
   3068      proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
   3069  RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
   3070 
   3071  // fraction_loss
   3072  std::vector<std::optional<uint64_t>> fraction_loss_values = DecodeDeltas(
   3073      proto.fraction_loss_deltas(), proto.fraction_loss(), number_of_deltas);
   3074  RTC_PARSE_CHECK_OR_RETURN_EQ(fraction_loss_values.size(), number_of_deltas);
   3075 
   3076  // total_packets
   3077  std::vector<std::optional<uint64_t>> total_packets_values = DecodeDeltas(
   3078      proto.total_packets_deltas(), proto.total_packets(), number_of_deltas);
   3079  RTC_PARSE_CHECK_OR_RETURN_EQ(total_packets_values.size(), number_of_deltas);
   3080 
   3081  // Populate events from decoded deltas
   3082  for (size_t i = 0; i < number_of_deltas; ++i) {
   3083    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
   3084    int64_t timestamp_ms;
   3085    RTC_PARSE_CHECK_OR_RETURN(
   3086        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   3087 
   3088    RTC_PARSE_CHECK_OR_RETURN(bitrate_bps_values[i].has_value());
   3089    RTC_PARSE_CHECK_OR_RETURN_LE(bitrate_bps_values[i].value(),
   3090                                 std::numeric_limits<uint32_t>::max());
   3091    const uint32_t bitrate_bps =
   3092        static_cast<uint32_t>(bitrate_bps_values[i].value());
   3093 
   3094    RTC_PARSE_CHECK_OR_RETURN(fraction_loss_values[i].has_value());
   3095    RTC_PARSE_CHECK_OR_RETURN_LE(fraction_loss_values[i].value(),
   3096                                 std::numeric_limits<uint32_t>::max());
   3097    const uint32_t fraction_loss =
   3098        static_cast<uint32_t>(fraction_loss_values[i].value());
   3099 
   3100    RTC_PARSE_CHECK_OR_RETURN(total_packets_values[i].has_value());
   3101    RTC_PARSE_CHECK_OR_RETURN_LE(total_packets_values[i].value(),
   3102                                 std::numeric_limits<uint32_t>::max());
   3103    const uint32_t total_packets =
   3104        static_cast<uint32_t>(total_packets_values[i].value());
   3105 
   3106    bwe_loss_updates_.emplace_back(Timestamp::Millis(timestamp_ms), bitrate_bps,
   3107                                   fraction_loss, total_packets);
   3108  }
   3109  return ParseStatus::Success();
   3110 }
   3111 
   3112 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweDelayBasedUpdate(
   3113    const rtclog2::DelayBasedBweUpdates& proto) {
   3114  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3115  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
   3116  RTC_PARSE_CHECK_OR_RETURN(proto.has_detector_state());
   3117 
   3118  // Base event
   3119  const BandwidthUsage base_detector_state =
   3120      GetRuntimeDetectorState(proto.detector_state());
   3121  bwe_delay_updates_.emplace_back(Timestamp::Millis(proto.timestamp_ms()),
   3122                                  proto.bitrate_bps(), base_detector_state);
   3123 
   3124  const size_t number_of_deltas =
   3125      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   3126  if (number_of_deltas == 0) {
   3127    return ParseStatus::Success();
   3128  }
   3129 
   3130  // timestamp_ms
   3131  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   3132      DecodeDeltas(proto.timestamp_ms_deltas(),
   3133                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   3134  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   3135 
   3136  // bitrate_bps
   3137  std::vector<std::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
   3138      proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
   3139  RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
   3140 
   3141  // detector_state
   3142  std::vector<std::optional<uint64_t>> detector_state_values = DecodeDeltas(
   3143      proto.detector_state_deltas(),
   3144      static_cast<uint64_t>(proto.detector_state()), number_of_deltas);
   3145  RTC_PARSE_CHECK_OR_RETURN_EQ(detector_state_values.size(), number_of_deltas);
   3146 
   3147  // Populate events from decoded deltas
   3148  for (size_t i = 0; i < number_of_deltas; ++i) {
   3149    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
   3150    int64_t timestamp_ms;
   3151    RTC_PARSE_CHECK_OR_RETURN(
   3152        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   3153 
   3154    RTC_PARSE_CHECK_OR_RETURN(bitrate_bps_values[i].has_value());
   3155    RTC_PARSE_CHECK_OR_RETURN_LE(bitrate_bps_values[i].value(),
   3156                                 std::numeric_limits<uint32_t>::max());
   3157    const uint32_t bitrate_bps =
   3158        static_cast<uint32_t>(bitrate_bps_values[i].value());
   3159 
   3160    RTC_PARSE_CHECK_OR_RETURN(detector_state_values[i].has_value());
   3161    const auto detector_state =
   3162        static_cast<rtclog2::DelayBasedBweUpdates::DetectorState>(
   3163            detector_state_values[i].value());
   3164 
   3165    bwe_delay_updates_.emplace_back(Timestamp::Millis(timestamp_ms),
   3166                                    bitrate_bps,
   3167                                    GetRuntimeDetectorState(detector_state));
   3168  }
   3169  return ParseStatus::Success();
   3170 }
   3171 
   3172 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeClusterCreated(
   3173    const rtclog2::BweProbeCluster& proto) {
   3174  LoggedBweProbeClusterCreatedEvent probe_cluster;
   3175  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3176  probe_cluster.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3177  RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
   3178  probe_cluster.id = proto.id();
   3179  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
   3180  probe_cluster.bitrate_bps = proto.bitrate_bps();
   3181  RTC_PARSE_CHECK_OR_RETURN(proto.has_min_packets());
   3182  probe_cluster.min_packets = proto.min_packets();
   3183  RTC_PARSE_CHECK_OR_RETURN(proto.has_min_bytes());
   3184  probe_cluster.min_bytes = proto.min_bytes();
   3185 
   3186  bwe_probe_cluster_created_events_.push_back(probe_cluster);
   3187 
   3188  // TODO(terelius): Should we delta encode this event type?
   3189  return ParseStatus::Success();
   3190 }
   3191 
   3192 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeSuccessEvent(
   3193    const rtclog2::BweProbeResultSuccess& proto) {
   3194  LoggedBweProbeSuccessEvent probe_result;
   3195  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3196  probe_result.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3197  RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
   3198  probe_result.id = proto.id();
   3199  RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
   3200  probe_result.bitrate_bps = proto.bitrate_bps();
   3201 
   3202  bwe_probe_success_events_.push_back(probe_result);
   3203 
   3204  // TODO(terelius): Should we delta encode this event type?
   3205  return ParseStatus::Success();
   3206 }
   3207 
   3208 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeFailureEvent(
   3209    const rtclog2::BweProbeResultFailure& proto) {
   3210  LoggedBweProbeFailureEvent probe_result;
   3211  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3212  probe_result.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3213  RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
   3214  probe_result.id = proto.id();
   3215  RTC_PARSE_CHECK_OR_RETURN(proto.has_failure());
   3216  probe_result.failure_reason = GetRuntimeProbeFailureReason(proto.failure());
   3217 
   3218  bwe_probe_failure_events_.push_back(probe_result);
   3219 
   3220  // TODO(terelius): Should we delta encode this event type?
   3221  return ParseStatus::Success();
   3222 }
   3223 
   3224 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreFrameDecodedEvents(
   3225    const rtclog2::FrameDecodedEvents& proto) {
   3226  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3227  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
   3228  RTC_PARSE_CHECK_OR_RETURN(proto.has_render_time_ms());
   3229  RTC_PARSE_CHECK_OR_RETURN(proto.has_width());
   3230  RTC_PARSE_CHECK_OR_RETURN(proto.has_height());
   3231  RTC_PARSE_CHECK_OR_RETURN(proto.has_codec());
   3232  RTC_PARSE_CHECK_OR_RETURN(proto.has_qp());
   3233 
   3234  LoggedFrameDecoded base_frame;
   3235  base_frame.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3236  base_frame.ssrc = proto.ssrc();
   3237  base_frame.render_time_ms = proto.render_time_ms();
   3238  base_frame.width = proto.width();
   3239  base_frame.height = proto.height();
   3240  base_frame.codec = GetRuntimeCodecType(proto.codec());
   3241  RTC_PARSE_CHECK_OR_RETURN_GE(proto.qp(), 0);
   3242  RTC_PARSE_CHECK_OR_RETURN_LE(proto.qp(), 255);
   3243  base_frame.qp = static_cast<uint8_t>(proto.qp());
   3244 
   3245  decoded_frames_[base_frame.ssrc].push_back(base_frame);
   3246 
   3247  const size_t number_of_deltas =
   3248      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   3249  if (number_of_deltas == 0) {
   3250    return ParseStatus::Success();
   3251  }
   3252 
   3253  // timestamp_ms
   3254  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   3255      DecodeDeltas(proto.timestamp_ms_deltas(),
   3256                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   3257  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   3258 
   3259  // SSRC
   3260  std::vector<std::optional<uint64_t>> ssrc_values =
   3261      DecodeDeltas(proto.ssrc_deltas(), proto.ssrc(), number_of_deltas);
   3262  RTC_PARSE_CHECK_OR_RETURN_EQ(ssrc_values.size(), number_of_deltas);
   3263 
   3264  // render_time_ms
   3265  std::vector<std::optional<uint64_t>> render_time_ms_values =
   3266      DecodeDeltas(proto.render_time_ms_deltas(),
   3267                   ToUnsigned(proto.render_time_ms()), number_of_deltas);
   3268  RTC_PARSE_CHECK_OR_RETURN_EQ(render_time_ms_values.size(), number_of_deltas);
   3269 
   3270  // width
   3271  std::vector<std::optional<uint64_t>> width_values = DecodeDeltas(
   3272      proto.width_deltas(), ToUnsigned(proto.width()), number_of_deltas);
   3273  RTC_PARSE_CHECK_OR_RETURN_EQ(width_values.size(), number_of_deltas);
   3274 
   3275  // height
   3276  std::vector<std::optional<uint64_t>> height_values = DecodeDeltas(
   3277      proto.height_deltas(), ToUnsigned(proto.height()), number_of_deltas);
   3278  RTC_PARSE_CHECK_OR_RETURN_EQ(height_values.size(), number_of_deltas);
   3279 
   3280  // codec
   3281  std::vector<std::optional<uint64_t>> codec_values =
   3282      DecodeDeltas(proto.codec_deltas(), static_cast<uint64_t>(proto.codec()),
   3283                   number_of_deltas);
   3284  RTC_PARSE_CHECK_OR_RETURN_EQ(codec_values.size(), number_of_deltas);
   3285 
   3286  // qp
   3287  std::vector<std::optional<uint64_t>> qp_values =
   3288      DecodeDeltas(proto.qp_deltas(), proto.qp(), number_of_deltas);
   3289  RTC_PARSE_CHECK_OR_RETURN_EQ(qp_values.size(), number_of_deltas);
   3290 
   3291  // Populate events from decoded deltas
   3292  for (size_t i = 0; i < number_of_deltas; ++i) {
   3293    LoggedFrameDecoded frame;
   3294    int64_t timestamp_ms;
   3295    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
   3296    RTC_PARSE_CHECK_OR_RETURN(
   3297        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   3298    frame.timestamp = Timestamp::Millis(timestamp_ms);
   3299 
   3300    RTC_PARSE_CHECK_OR_RETURN(ssrc_values[i].has_value());
   3301    RTC_PARSE_CHECK_OR_RETURN_LE(ssrc_values[i].value(),
   3302                                 std::numeric_limits<uint32_t>::max());
   3303    frame.ssrc = static_cast<uint32_t>(ssrc_values[i].value());
   3304 
   3305    RTC_PARSE_CHECK_OR_RETURN(render_time_ms_values[i].has_value());
   3306    RTC_PARSE_CHECK_OR_RETURN(
   3307        ToSigned(render_time_ms_values[i].value(), &frame.render_time_ms));
   3308 
   3309    RTC_PARSE_CHECK_OR_RETURN(width_values[i].has_value());
   3310    RTC_PARSE_CHECK_OR_RETURN(ToSigned(width_values[i].value(), &frame.width));
   3311 
   3312    RTC_PARSE_CHECK_OR_RETURN(height_values[i].has_value());
   3313    RTC_PARSE_CHECK_OR_RETURN(
   3314        ToSigned(height_values[i].value(), &frame.height));
   3315 
   3316    RTC_PARSE_CHECK_OR_RETURN(codec_values[i].has_value());
   3317    frame.codec =
   3318        GetRuntimeCodecType(static_cast<rtclog2::FrameDecodedEvents::Codec>(
   3319            codec_values[i].value()));
   3320 
   3321    RTC_PARSE_CHECK_OR_RETURN(qp_values[i].has_value());
   3322    RTC_PARSE_CHECK_OR_RETURN_LE(qp_values[i].value(),
   3323                                 std::numeric_limits<uint8_t>::max());
   3324    frame.qp = static_cast<uint8_t>(qp_values[i].value());
   3325 
   3326    decoded_frames_[frame.ssrc].push_back(frame);
   3327  }
   3328  return ParseStatus::Success();
   3329 }
   3330 
   3331 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreGenericPacketSentEvent(
   3332    const rtclog2::GenericPacketSent& proto) {
   3333  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3334 
   3335  // Base event
   3336  RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
   3337  RTC_PARSE_CHECK_OR_RETURN(proto.has_overhead_length());
   3338  RTC_PARSE_CHECK_OR_RETURN(proto.has_payload_length());
   3339  RTC_PARSE_CHECK_OR_RETURN(proto.has_padding_length());
   3340 
   3341  generic_packets_sent_.push_back(
   3342      {Timestamp::Millis(proto.timestamp_ms()), proto.packet_number(),
   3343       static_cast<size_t>(proto.overhead_length()),
   3344       static_cast<size_t>(proto.payload_length()),
   3345       static_cast<size_t>(proto.padding_length())});
   3346 
   3347  const size_t number_of_deltas =
   3348      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   3349  if (number_of_deltas == 0) {
   3350    return ParseStatus::Success();
   3351  }
   3352 
   3353  // timestamp_ms
   3354  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   3355      DecodeDeltas(proto.timestamp_ms_deltas(),
   3356                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   3357  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   3358 
   3359  // packet_number
   3360  std::vector<std::optional<uint64_t>> packet_number_values =
   3361      DecodeDeltas(proto.packet_number_deltas(),
   3362                   ToUnsigned(proto.packet_number()), number_of_deltas);
   3363  RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
   3364 
   3365  std::vector<std::optional<uint64_t>> overhead_length_values =
   3366      DecodeDeltas(proto.overhead_length_deltas(), proto.overhead_length(),
   3367                   number_of_deltas);
   3368  RTC_PARSE_CHECK_OR_RETURN_EQ(overhead_length_values.size(), number_of_deltas);
   3369 
   3370  std::vector<std::optional<uint64_t>> payload_length_values = DecodeDeltas(
   3371      proto.payload_length_deltas(), proto.payload_length(), number_of_deltas);
   3372  RTC_PARSE_CHECK_OR_RETURN_EQ(payload_length_values.size(), number_of_deltas);
   3373 
   3374  std::vector<std::optional<uint64_t>> padding_length_values = DecodeDeltas(
   3375      proto.padding_length_deltas(), proto.padding_length(), number_of_deltas);
   3376  RTC_PARSE_CHECK_OR_RETURN_EQ(padding_length_values.size(), number_of_deltas);
   3377 
   3378  for (size_t i = 0; i < number_of_deltas; i++) {
   3379    int64_t timestamp_ms;
   3380    RTC_PARSE_CHECK_OR_RETURN(
   3381        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   3382    int64_t packet_number;
   3383    RTC_PARSE_CHECK_OR_RETURN(
   3384        ToSigned(packet_number_values[i].value(), &packet_number));
   3385    RTC_PARSE_CHECK_OR_RETURN(overhead_length_values[i].has_value());
   3386    RTC_PARSE_CHECK_OR_RETURN(payload_length_values[i].has_value());
   3387    RTC_PARSE_CHECK_OR_RETURN(padding_length_values[i].has_value());
   3388    generic_packets_sent_.push_back(
   3389        {Timestamp::Millis(timestamp_ms), packet_number,
   3390         static_cast<size_t>(overhead_length_values[i].value()),
   3391         static_cast<size_t>(payload_length_values[i].value()),
   3392         static_cast<size_t>(padding_length_values[i].value())});
   3393  }
   3394  return ParseStatus::Success();
   3395 }
   3396 
   3397 ParsedRtcEventLog::ParseStatus
   3398 ParsedRtcEventLog::StoreGenericPacketReceivedEvent(
   3399    const rtclog2::GenericPacketReceived& proto) {
   3400  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3401 
   3402  // Base event
   3403  RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
   3404  RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_length());
   3405 
   3406  generic_packets_received_.push_back({Timestamp::Millis(proto.timestamp_ms()),
   3407                                       proto.packet_number(),
   3408                                       proto.packet_length()});
   3409 
   3410  const size_t number_of_deltas =
   3411      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   3412  if (number_of_deltas == 0) {
   3413    return ParseStatus::Success();
   3414  }
   3415 
   3416  // timestamp_ms
   3417  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   3418      DecodeDeltas(proto.timestamp_ms_deltas(),
   3419                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   3420  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   3421 
   3422  // packet_number
   3423  std::vector<std::optional<uint64_t>> packet_number_values =
   3424      DecodeDeltas(proto.packet_number_deltas(),
   3425                   ToUnsigned(proto.packet_number()), number_of_deltas);
   3426  RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
   3427 
   3428  std::vector<std::optional<uint64_t>> packet_length_values = DecodeDeltas(
   3429      proto.packet_length_deltas(), proto.packet_length(), number_of_deltas);
   3430  RTC_PARSE_CHECK_OR_RETURN_EQ(packet_length_values.size(), number_of_deltas);
   3431 
   3432  for (size_t i = 0; i < number_of_deltas; i++) {
   3433    int64_t timestamp_ms;
   3434    RTC_PARSE_CHECK_OR_RETURN(
   3435        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   3436    int64_t packet_number;
   3437    RTC_PARSE_CHECK_OR_RETURN(
   3438        ToSigned(packet_number_values[i].value(), &packet_number));
   3439    RTC_PARSE_CHECK_OR_RETURN_LE(packet_length_values[i].value(),
   3440                                 std::numeric_limits<int32_t>::max());
   3441    int32_t packet_length =
   3442        static_cast<int32_t>(packet_length_values[i].value());
   3443    generic_packets_received_.push_back(
   3444        {Timestamp::Millis(timestamp_ms), packet_number, packet_length});
   3445  }
   3446  return ParseStatus::Success();
   3447 }
   3448 
   3449 ParsedRtcEventLog::ParseStatus
   3450 ParsedRtcEventLog::StoreAudioNetworkAdaptationEvent(
   3451    const rtclog2::AudioNetworkAdaptations& proto) {
   3452  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3453 
   3454  // Base event
   3455  {
   3456    AudioEncoderRuntimeConfig runtime_config;
   3457    if (proto.has_bitrate_bps()) {
   3458      runtime_config.bitrate_bps = proto.bitrate_bps();
   3459    }
   3460    if (proto.has_frame_length_ms()) {
   3461      runtime_config.frame_length_ms = proto.frame_length_ms();
   3462    }
   3463    if (proto.has_uplink_packet_loss_fraction()) {
   3464      float uplink_packet_loss_fraction;
   3465      RTC_PARSE_CHECK_OR_RETURN(ParsePacketLossFractionFromProtoFormat(
   3466          proto.uplink_packet_loss_fraction(), &uplink_packet_loss_fraction));
   3467      runtime_config.uplink_packet_loss_fraction = uplink_packet_loss_fraction;
   3468    }
   3469    if (proto.has_enable_fec()) {
   3470      runtime_config.enable_fec = proto.enable_fec();
   3471    }
   3472    if (proto.has_enable_dtx()) {
   3473      runtime_config.enable_dtx = proto.enable_dtx();
   3474    }
   3475    if (proto.has_num_channels()) {
   3476      // Note: Encoding N as N-1 only done for `num_channels_deltas`.
   3477      runtime_config.num_channels = proto.num_channels();
   3478    }
   3479    audio_network_adaptation_events_.emplace_back(
   3480        Timestamp::Millis(proto.timestamp_ms()), runtime_config);
   3481  }
   3482 
   3483  const size_t number_of_deltas =
   3484      proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
   3485  if (number_of_deltas == 0) {
   3486    return ParseStatus::Success();
   3487  }
   3488 
   3489  // timestamp_ms
   3490  std::vector<std::optional<uint64_t>> timestamp_ms_values =
   3491      DecodeDeltas(proto.timestamp_ms_deltas(),
   3492                   ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   3493  RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
   3494 
   3495  // bitrate_bps
   3496  const std::optional<uint64_t> unsigned_base_bitrate_bps =
   3497      proto.has_bitrate_bps()
   3498          ? std::optional<uint64_t>(ToUnsigned(proto.bitrate_bps()))
   3499          : std::optional<uint64_t>();
   3500  std::vector<std::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
   3501      proto.bitrate_bps_deltas(), unsigned_base_bitrate_bps, number_of_deltas);
   3502  RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
   3503 
   3504  // frame_length_ms
   3505  const std::optional<uint64_t> unsigned_base_frame_length_ms =
   3506      proto.has_frame_length_ms()
   3507          ? std::optional<uint64_t>(ToUnsigned(proto.frame_length_ms()))
   3508          : std::optional<uint64_t>();
   3509  std::vector<std::optional<uint64_t>> frame_length_ms_values =
   3510      DecodeDeltas(proto.frame_length_ms_deltas(),
   3511                   unsigned_base_frame_length_ms, number_of_deltas);
   3512  RTC_PARSE_CHECK_OR_RETURN_EQ(frame_length_ms_values.size(), number_of_deltas);
   3513 
   3514  // uplink_packet_loss_fraction
   3515  const std::optional<uint64_t> uplink_packet_loss_fraction =
   3516      proto.has_uplink_packet_loss_fraction()
   3517          ? std::optional<uint64_t>(proto.uplink_packet_loss_fraction())
   3518          : std::optional<uint64_t>();
   3519  std::vector<std::optional<uint64_t>> uplink_packet_loss_fraction_values =
   3520      DecodeDeltas(proto.uplink_packet_loss_fraction_deltas(),
   3521                   uplink_packet_loss_fraction, number_of_deltas);
   3522  RTC_PARSE_CHECK_OR_RETURN_EQ(uplink_packet_loss_fraction_values.size(),
   3523                               number_of_deltas);
   3524 
   3525  // enable_fec
   3526  const std::optional<uint64_t> enable_fec =
   3527      proto.has_enable_fec() ? std::optional<uint64_t>(proto.enable_fec())
   3528                             : std::optional<uint64_t>();
   3529  std::vector<std::optional<uint64_t>> enable_fec_values =
   3530      DecodeDeltas(proto.enable_fec_deltas(), enable_fec, number_of_deltas);
   3531  RTC_PARSE_CHECK_OR_RETURN_EQ(enable_fec_values.size(), number_of_deltas);
   3532 
   3533  // enable_dtx
   3534  const std::optional<uint64_t> enable_dtx =
   3535      proto.has_enable_dtx() ? std::optional<uint64_t>(proto.enable_dtx())
   3536                             : std::optional<uint64_t>();
   3537  std::vector<std::optional<uint64_t>> enable_dtx_values =
   3538      DecodeDeltas(proto.enable_dtx_deltas(), enable_dtx, number_of_deltas);
   3539  RTC_PARSE_CHECK_OR_RETURN_EQ(enable_dtx_values.size(), number_of_deltas);
   3540 
   3541  // num_channels
   3542  // Note: For delta encoding, all num_channel values, including the base,
   3543  // were shifted down by one, but in the base event, they were not.
   3544  // We likewise shift the base event down by one, to get the same base as
   3545  // encoding had, but then shift all of the values (except the base) back up
   3546  // to their original value.
   3547  std::optional<uint64_t> shifted_base_num_channels;
   3548  if (proto.has_num_channels()) {
   3549    shifted_base_num_channels =
   3550        std::optional<uint64_t>(proto.num_channels() - 1);
   3551  }
   3552  std::vector<std::optional<uint64_t>> num_channels_values = DecodeDeltas(
   3553      proto.num_channels_deltas(), shifted_base_num_channels, number_of_deltas);
   3554  for (size_t i = 0; i < num_channels_values.size(); ++i) {
   3555    if (num_channels_values[i].has_value()) {
   3556      num_channels_values[i] = num_channels_values[i].value() + 1;
   3557    }
   3558  }
   3559  RTC_PARSE_CHECK_OR_RETURN_EQ(num_channels_values.size(), number_of_deltas);
   3560 
   3561  // Populate events from decoded deltas
   3562  for (size_t i = 0; i < number_of_deltas; ++i) {
   3563    RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
   3564    int64_t timestamp_ms;
   3565    RTC_PARSE_CHECK_OR_RETURN(
   3566        ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
   3567 
   3568    AudioEncoderRuntimeConfig runtime_config;
   3569    if (bitrate_bps_values[i].has_value()) {
   3570      int signed_bitrate_bps;
   3571      RTC_PARSE_CHECK_OR_RETURN(
   3572          ToSigned(bitrate_bps_values[i].value(), &signed_bitrate_bps));
   3573      runtime_config.bitrate_bps = signed_bitrate_bps;
   3574    }
   3575    if (frame_length_ms_values[i].has_value()) {
   3576      int signed_frame_length_ms;
   3577      RTC_PARSE_CHECK_OR_RETURN(
   3578          ToSigned(frame_length_ms_values[i].value(), &signed_frame_length_ms));
   3579      runtime_config.frame_length_ms = signed_frame_length_ms;
   3580    }
   3581    if (uplink_packet_loss_fraction_values[i].has_value()) {
   3582      float uplink_packet_loss_fraction2;
   3583      RTC_PARSE_CHECK_OR_RETURN(IsValueInRangeForNumericType<uint32_t>(
   3584          uplink_packet_loss_fraction_values[i].value()));
   3585      RTC_PARSE_CHECK_OR_RETURN(ParsePacketLossFractionFromProtoFormat(
   3586          static_cast<uint32_t>(uplink_packet_loss_fraction_values[i].value()),
   3587          &uplink_packet_loss_fraction2));
   3588      runtime_config.uplink_packet_loss_fraction = uplink_packet_loss_fraction2;
   3589    }
   3590    if (enable_fec_values[i].has_value()) {
   3591      RTC_PARSE_CHECK_OR_RETURN(
   3592          IsValueInRangeForNumericType<bool>(enable_fec_values[i].value()));
   3593      runtime_config.enable_fec =
   3594          static_cast<bool>(enable_fec_values[i].value());
   3595    }
   3596    if (enable_dtx_values[i].has_value()) {
   3597      RTC_PARSE_CHECK_OR_RETURN(
   3598          IsValueInRangeForNumericType<bool>(enable_dtx_values[i].value()));
   3599      runtime_config.enable_dtx =
   3600          static_cast<bool>(enable_dtx_values[i].value());
   3601    }
   3602    if (num_channels_values[i].has_value()) {
   3603      RTC_PARSE_CHECK_OR_RETURN(
   3604          IsValueInRangeForNumericType<size_t>(num_channels_values[i].value()));
   3605      runtime_config.num_channels =
   3606          static_cast<size_t>(num_channels_values[i].value());
   3607    }
   3608    audio_network_adaptation_events_.emplace_back(
   3609        Timestamp::Millis(timestamp_ms), runtime_config);
   3610  }
   3611  return ParseStatus::Success();
   3612 }
   3613 
   3614 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreDtlsTransportState(
   3615    const rtclog2::DtlsTransportStateEvent& proto) {
   3616  LoggedDtlsTransportState dtls_state;
   3617  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3618  dtls_state.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3619 
   3620  RTC_PARSE_CHECK_OR_RETURN(proto.has_dtls_transport_state());
   3621  dtls_state.dtls_transport_state =
   3622      GetRuntimeDtlsTransportState(proto.dtls_transport_state());
   3623 
   3624  dtls_transport_states_.push_back(dtls_state);
   3625  return ParseStatus::Success();
   3626 }
   3627 
   3628 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreDtlsWritableState(
   3629    const rtclog2::DtlsWritableState& proto) {
   3630  LoggedDtlsWritableState dtls_writable_state;
   3631  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3632  dtls_writable_state.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3633  RTC_PARSE_CHECK_OR_RETURN(proto.has_writable());
   3634  dtls_writable_state.writable = proto.writable();
   3635 
   3636  dtls_writable_states_.push_back(dtls_writable_state);
   3637  return ParseStatus::Success();
   3638 }
   3639 
   3640 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidatePairConfig(
   3641    const rtclog2::IceCandidatePairConfig& proto) {
   3642  LoggedIceCandidatePairConfig ice_config;
   3643  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3644  ice_config.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3645 
   3646  RTC_PARSE_CHECK_OR_RETURN(proto.has_config_type());
   3647  ice_config.type = GetRuntimeIceCandidatePairConfigType(proto.config_type());
   3648  RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id());
   3649  ice_config.candidate_pair_id = proto.candidate_pair_id();
   3650  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_candidate_type());
   3651  RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType(
   3652      proto.local_candidate_type(), ice_config.local_candidate_type));
   3653  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_relay_protocol());
   3654  ice_config.local_relay_protocol =
   3655      GetRuntimeIceCandidatePairProtocol(proto.local_relay_protocol());
   3656  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_network_type());
   3657  ice_config.local_network_type =
   3658      GetRuntimeIceCandidateNetworkType(proto.local_network_type());
   3659  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_address_family());
   3660  ice_config.local_address_family =
   3661      GetRuntimeIceCandidatePairAddressFamily(proto.local_address_family());
   3662  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_candidate_type());
   3663  RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType(
   3664      proto.remote_candidate_type(), ice_config.remote_candidate_type));
   3665  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_address_family());
   3666  ice_config.remote_address_family =
   3667      GetRuntimeIceCandidatePairAddressFamily(proto.remote_address_family());
   3668  RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_protocol());
   3669  ice_config.candidate_pair_protocol =
   3670      GetRuntimeIceCandidatePairProtocol(proto.candidate_pair_protocol());
   3671 
   3672  ice_candidate_pair_configs_.push_back(ice_config);
   3673 
   3674  // TODO(terelius): Should we delta encode this event type?
   3675  return ParseStatus::Success();
   3676 }
   3677 
   3678 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidateEvent(
   3679    const rtclog2::IceCandidatePairEvent& proto) {
   3680  LoggedIceCandidatePairEvent ice_event;
   3681  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3682  ice_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3683  RTC_PARSE_CHECK_OR_RETURN(proto.has_event_type());
   3684  ice_event.type = GetRuntimeIceCandidatePairEventType(proto.event_type());
   3685  RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id());
   3686  ice_event.candidate_pair_id = proto.candidate_pair_id();
   3687  // TODO(zstein): Make the transaction_id field required once all old versions
   3688  // of the log (which don't have the field) are obsolete.
   3689  ice_event.transaction_id =
   3690      proto.has_transaction_id() ? proto.transaction_id() : 0;
   3691 
   3692  ice_candidate_pair_events_.push_back(ice_event);
   3693 
   3694  // TODO(terelius): Should we delta encode this event type?
   3695  return ParseStatus::Success();
   3696 }
   3697 
   3698 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreVideoRecvConfig(
   3699    const rtclog2::VideoRecvStreamConfig& proto) {
   3700  LoggedVideoRecvConfig stream;
   3701  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3702  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3703  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
   3704  stream.config.remote_ssrc = proto.remote_ssrc();
   3705  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
   3706  stream.config.local_ssrc = proto.local_ssrc();
   3707  if (proto.has_rtx_ssrc()) {
   3708    stream.config.rtx_ssrc = proto.rtx_ssrc();
   3709  }
   3710  if (proto.has_header_extensions()) {
   3711    stream.config.rtp_extensions =
   3712        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
   3713  }
   3714  video_recv_configs_.push_back(stream);
   3715  return ParseStatus::Success();
   3716 }
   3717 
   3718 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreVideoSendConfig(
   3719    const rtclog2::VideoSendStreamConfig& proto) {
   3720  LoggedVideoSendConfig stream;
   3721  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3722  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3723  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
   3724  stream.config.local_ssrc = proto.ssrc();
   3725  if (proto.has_rtx_ssrc()) {
   3726    stream.config.rtx_ssrc = proto.rtx_ssrc();
   3727  }
   3728  if (proto.has_header_extensions()) {
   3729    stream.config.rtp_extensions =
   3730        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
   3731  }
   3732  video_send_configs_.push_back(stream);
   3733  return ParseStatus::Success();
   3734 }
   3735 
   3736 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioRecvConfig(
   3737    const rtclog2::AudioRecvStreamConfig& proto) {
   3738  LoggedAudioRecvConfig stream;
   3739  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3740  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3741  RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
   3742  stream.config.remote_ssrc = proto.remote_ssrc();
   3743  RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
   3744  stream.config.local_ssrc = proto.local_ssrc();
   3745  if (proto.has_header_extensions()) {
   3746    stream.config.rtp_extensions =
   3747        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
   3748  }
   3749  audio_recv_configs_.push_back(stream);
   3750  return ParseStatus::Success();
   3751 }
   3752 
   3753 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioSendConfig(
   3754    const rtclog2::AudioSendStreamConfig& proto) {
   3755  LoggedAudioSendConfig stream;
   3756  RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   3757  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   3758  RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
   3759  stream.config.local_ssrc = proto.ssrc();
   3760  if (proto.has_header_extensions()) {
   3761    stream.config.rtp_extensions =
   3762        GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
   3763  }
   3764  audio_send_configs_.push_back(stream);
   3765  return ParseStatus::Success();
   3766 }
   3767 
   3768 }  // namespace webrtc