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