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