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(), ×tamp_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(), ×tamp_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(), ×tamp_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(), ×tamp_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(), ×tamp_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(), ×tamp_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(), ×tamp_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(), ×tamp_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(), ×tamp_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(), ×tamp_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