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