• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "logging/rtc_event_log/rtc_event_log_parser.h"
12 
13 #include <stdint.h>
14 #include <string.h>
15 
16 #include <algorithm>
17 #include <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::__anonf5bf4f890111::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   first_log_segment_ = LogSegment(0, std::numeric_limits<int64_t>::max());
1080 
1081   incoming_rtp_extensions_maps_.clear();
1082   outgoing_rtp_extensions_maps_.clear();
1083 }
1084 
ParseFile(const std::string & filename)1085 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseFile(
1086     const std::string& filename) {
1087   std::ifstream file(  // no-presubmit-check TODO(webrtc:8982)
1088       filename, std::ios_base::in | std::ios_base::binary);
1089   if (!file.good() || !file.is_open()) {
1090     RTC_LOG(LS_WARNING) << "Could not open file for reading.";
1091     RTC_PARSE_CHECK_OR_RETURN(file.good() && file.is_open());
1092   }
1093 
1094   return ParseStream(file);
1095 }
1096 
ParseString(const std::string & s)1097 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseString(
1098     const std::string& s) {
1099   std::istringstream stream(  // no-presubmit-check TODO(webrtc:8982)
1100       s, std::ios_base::in | std::ios_base::binary);
1101   return ParseStream(stream);
1102 }
1103 
ParseStream(std::istream & stream)1104 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStream(
1105     std::istream& stream) {  // no-presubmit-check TODO(webrtc:8982)
1106   Clear();
1107   ParseStatus status = ParseStreamInternal(stream);
1108 
1109   // Cache the configured SSRCs.
1110   for (const auto& video_recv_config : video_recv_configs()) {
1111     incoming_video_ssrcs_.insert(video_recv_config.config.remote_ssrc);
1112     incoming_video_ssrcs_.insert(video_recv_config.config.rtx_ssrc);
1113     incoming_rtx_ssrcs_.insert(video_recv_config.config.rtx_ssrc);
1114   }
1115   for (const auto& video_send_config : video_send_configs()) {
1116     outgoing_video_ssrcs_.insert(video_send_config.config.local_ssrc);
1117     outgoing_video_ssrcs_.insert(video_send_config.config.rtx_ssrc);
1118     outgoing_rtx_ssrcs_.insert(video_send_config.config.rtx_ssrc);
1119   }
1120   for (const auto& audio_recv_config : audio_recv_configs()) {
1121     incoming_audio_ssrcs_.insert(audio_recv_config.config.remote_ssrc);
1122   }
1123   for (const auto& audio_send_config : audio_send_configs()) {
1124     outgoing_audio_ssrcs_.insert(audio_send_config.config.local_ssrc);
1125   }
1126 
1127   // ParseStreamInternal stores the RTP packets in a map indexed by SSRC.
1128   // Since we dont need rapid lookup based on SSRC after parsing, we move the
1129   // packets_streams from map to vector.
1130   incoming_rtp_packets_by_ssrc_.reserve(incoming_rtp_packets_map_.size());
1131   for (auto& kv : incoming_rtp_packets_map_) {
1132     incoming_rtp_packets_by_ssrc_.emplace_back(LoggedRtpStreamIncoming());
1133     incoming_rtp_packets_by_ssrc_.back().ssrc = kv.first;
1134     incoming_rtp_packets_by_ssrc_.back().incoming_packets =
1135         std::move(kv.second);
1136   }
1137   incoming_rtp_packets_map_.clear();
1138   outgoing_rtp_packets_by_ssrc_.reserve(outgoing_rtp_packets_map_.size());
1139   for (auto& kv : outgoing_rtp_packets_map_) {
1140     outgoing_rtp_packets_by_ssrc_.emplace_back(LoggedRtpStreamOutgoing());
1141     outgoing_rtp_packets_by_ssrc_.back().ssrc = kv.first;
1142     outgoing_rtp_packets_by_ssrc_.back().outgoing_packets =
1143         std::move(kv.second);
1144   }
1145   outgoing_rtp_packets_map_.clear();
1146 
1147   // Build PacketViews for easier iteration over RTP packets.
1148   for (const auto& stream : incoming_rtp_packets_by_ssrc_) {
1149     incoming_rtp_packet_views_by_ssrc_.emplace_back(
1150         LoggedRtpStreamView(stream.ssrc, stream.incoming_packets.data(),
1151                             stream.incoming_packets.size()));
1152   }
1153   for (const auto& stream : outgoing_rtp_packets_by_ssrc_) {
1154     outgoing_rtp_packet_views_by_ssrc_.emplace_back(
1155         LoggedRtpStreamView(stream.ssrc, stream.outgoing_packets.data(),
1156                             stream.outgoing_packets.size()));
1157   }
1158 
1159   // Set up convenience wrappers around the most commonly used RTCP types.
1160   for (const auto& incoming : incoming_rtcp_packets_) {
1161     const int64_t timestamp_us = incoming.rtcp.timestamp_us;
1162     const uint8_t* packet_begin = incoming.rtcp.raw_data.data();
1163     const uint8_t* packet_end = packet_begin + incoming.rtcp.raw_data.size();
1164     auto status = StoreRtcpBlocks(
1165         timestamp_us, packet_begin, packet_end, &incoming_sr_, &incoming_rr_,
1166         &incoming_xr_, &incoming_remb_, &incoming_nack_, &incoming_fir_,
1167         &incoming_pli_, &incoming_transport_feedback_,
1168         &incoming_loss_notification_);
1169     RTC_RETURN_IF_ERROR(status);
1170   }
1171 
1172   for (const auto& outgoing : outgoing_rtcp_packets_) {
1173     const int64_t timestamp_us = outgoing.rtcp.timestamp_us;
1174     const uint8_t* packet_begin = outgoing.rtcp.raw_data.data();
1175     const uint8_t* packet_end = packet_begin + outgoing.rtcp.raw_data.size();
1176     auto status = StoreRtcpBlocks(
1177         timestamp_us, packet_begin, packet_end, &outgoing_sr_, &outgoing_rr_,
1178         &outgoing_xr_, &outgoing_remb_, &outgoing_nack_, &outgoing_fir_,
1179         &outgoing_pli_, &outgoing_transport_feedback_,
1180         &outgoing_loss_notification_);
1181     RTC_RETURN_IF_ERROR(status);
1182   }
1183 
1184   // Store first and last timestamp events that might happen before the call is
1185   // connected or after the call is disconnected. Typical examples are
1186   // stream configurations and starting/stopping the log.
1187   // TODO(terelius): Figure out if we actually need to find the first and last
1188   // timestamp in the parser. It seems like this could be done by the caller.
1189   first_timestamp_ = std::numeric_limits<int64_t>::max();
1190   last_timestamp_ = std::numeric_limits<int64_t>::min();
1191   StoreFirstAndLastTimestamp(alr_state_events());
1192   StoreFirstAndLastTimestamp(route_change_events());
1193   for (const auto& audio_stream : audio_playout_events()) {
1194     // Audio playout events are grouped by SSRC.
1195     StoreFirstAndLastTimestamp(audio_stream.second);
1196   }
1197   StoreFirstAndLastTimestamp(audio_network_adaptation_events());
1198   StoreFirstAndLastTimestamp(bwe_probe_cluster_created_events());
1199   StoreFirstAndLastTimestamp(bwe_probe_failure_events());
1200   StoreFirstAndLastTimestamp(bwe_probe_success_events());
1201   StoreFirstAndLastTimestamp(bwe_delay_updates());
1202   StoreFirstAndLastTimestamp(bwe_loss_updates());
1203   StoreFirstAndLastTimestamp(dtls_transport_states());
1204   StoreFirstAndLastTimestamp(dtls_writable_states());
1205   StoreFirstAndLastTimestamp(ice_candidate_pair_configs());
1206   StoreFirstAndLastTimestamp(ice_candidate_pair_events());
1207   for (const auto& rtp_stream : incoming_rtp_packets_by_ssrc()) {
1208     StoreFirstAndLastTimestamp(rtp_stream.incoming_packets);
1209   }
1210   for (const auto& rtp_stream : outgoing_rtp_packets_by_ssrc()) {
1211     StoreFirstAndLastTimestamp(rtp_stream.outgoing_packets);
1212   }
1213   StoreFirstAndLastTimestamp(incoming_rtcp_packets());
1214   StoreFirstAndLastTimestamp(outgoing_rtcp_packets());
1215   StoreFirstAndLastTimestamp(generic_packets_sent_);
1216   StoreFirstAndLastTimestamp(generic_packets_received_);
1217   StoreFirstAndLastTimestamp(generic_acks_received_);
1218   StoreFirstAndLastTimestamp(remote_estimate_events_);
1219 
1220   // Stop events could be missing due to file size limits. If so, use the
1221   // last event, or the next start timestamp if available.
1222   // TODO(terelius): This could be improved. Instead of using the next start
1223   // event, we could use the timestamp of the the last previous regular event.
1224   auto start_iter = start_log_events().begin();
1225   auto stop_iter = stop_log_events().begin();
1226   int64_t start_us = first_timestamp();
1227   int64_t next_start_us = std::numeric_limits<int64_t>::max();
1228   int64_t stop_us = std::numeric_limits<int64_t>::max();
1229   if (start_iter != start_log_events().end()) {
1230     start_us = std::min(start_us, start_iter->log_time_us());
1231     ++start_iter;
1232     if (start_iter != start_log_events().end())
1233       next_start_us = start_iter->log_time_us();
1234   }
1235   if (stop_iter != stop_log_events().end()) {
1236     stop_us = stop_iter->log_time_us();
1237   }
1238   stop_us = std::min(stop_us, next_start_us);
1239   if (stop_us == std::numeric_limits<int64_t>::max() &&
1240       last_timestamp() != std::numeric_limits<int64_t>::min()) {
1241     stop_us = last_timestamp();
1242   }
1243   RTC_PARSE_CHECK_OR_RETURN_LE(start_us, stop_us);
1244   first_log_segment_ = LogSegment(start_us, stop_us);
1245 
1246   if (first_timestamp_ == std::numeric_limits<int64_t>::max() &&
1247       last_timestamp_ == std::numeric_limits<int64_t>::min()) {
1248     first_timestamp_ = last_timestamp_ = 0;
1249   }
1250 
1251   return status;
1252 }
1253 
ParseStreamInternal(std::istream & stream)1254 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStreamInternal(
1255     std::istream& stream) {  // no-presubmit-check TODO(webrtc:8982)
1256   constexpr uint64_t kMaxEventSize = 10000000;  // Sanity check.
1257   std::vector<char> buffer(0xFFFF);
1258 
1259   RTC_DCHECK(stream.good());
1260   while (1) {
1261     // Check whether we have reached end of file.
1262     stream.peek();
1263     if (stream.eof()) {
1264       break;
1265     }
1266 
1267     // Read the next message tag. Protobuf defines the message tag as
1268     // (field_number << 3) | wire_type. In the legacy encoding, the field number
1269     // is supposed to be 1 and the wire type for a length-delimited field is 2.
1270     // In the new encoding we still expect the wire type to be 2, but the field
1271     // number will be greater than 1.
1272     constexpr uint64_t kExpectedV1Tag = (1 << 3) | 2;
1273     size_t bytes_written = 0;
1274     ParsedRtcEventLog::ParseStatusOr<uint64_t> tag =
1275         ParseVarInt(stream, buffer.data(), &bytes_written);
1276     if (!tag.ok()) {
1277       RTC_LOG(LS_WARNING)
1278           << "Missing field tag from beginning of protobuf event.";
1279       RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
1280                                            kIncompleteLogError);
1281       return tag.status();
1282     }
1283     constexpr uint64_t kWireTypeMask = 0x07;
1284     const uint64_t wire_type = tag.value() & kWireTypeMask;
1285     if (wire_type != 2) {
1286       RTC_LOG(LS_WARNING) << "Expected field tag with wire type 2 (length "
1287                              "delimited message). Found wire type "
1288                           << wire_type;
1289       RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
1290                                            kIncompleteLogError);
1291       RTC_PARSE_CHECK_OR_RETURN_EQ(wire_type, 2);
1292     }
1293 
1294     // Read the length field.
1295     ParsedRtcEventLog::ParseStatusOr<uint64_t> message_length =
1296         ParseVarInt(stream, buffer.data(), &bytes_written);
1297     if (!message_length.ok()) {
1298       RTC_LOG(LS_WARNING) << "Missing message length after protobuf field tag.";
1299       RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
1300                                            kIncompleteLogError);
1301       return message_length.status();
1302     } else if (message_length.value() > kMaxEventSize) {
1303       RTC_LOG(LS_WARNING) << "Protobuf message length is too large.";
1304       RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
1305                                            kIncompleteLogError);
1306       RTC_PARSE_CHECK_OR_RETURN_LE(message_length.value(), kMaxEventSize);
1307     }
1308 
1309     // Read the next protobuf event to a temporary char buffer.
1310     if (buffer.size() < bytes_written + message_length.value())
1311       buffer.resize(bytes_written + message_length.value());
1312     stream.read(buffer.data() + bytes_written, message_length.value());
1313     if (stream.gcount() != static_cast<int>(message_length.value())) {
1314       RTC_LOG(LS_WARNING) << "Failed to read protobuf message.";
1315       RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
1316                                            kIncompleteLogError);
1317       RTC_PARSE_CHECK_OR_RETURN(false);
1318     }
1319     size_t buffer_size = bytes_written + message_length.value();
1320 
1321     if (tag.value() == kExpectedV1Tag) {
1322       // Parse the protobuf event from the buffer.
1323       rtclog::EventStream event_stream;
1324       if (!event_stream.ParseFromArray(buffer.data(), buffer_size)) {
1325         RTC_LOG(LS_WARNING)
1326             << "Failed to parse legacy-format protobuf message.";
1327         RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
1328                                              kIncompleteLogError);
1329         RTC_PARSE_CHECK_OR_RETURN(false);
1330       }
1331 
1332       RTC_PARSE_CHECK_OR_RETURN_EQ(event_stream.stream_size(), 1);
1333       auto status = StoreParsedLegacyEvent(event_stream.stream(0));
1334       RTC_RETURN_IF_ERROR(status);
1335     } else {
1336       // Parse the protobuf event from the buffer.
1337       rtclog2::EventStream event_stream;
1338       if (!event_stream.ParseFromArray(buffer.data(), buffer_size)) {
1339         RTC_LOG(LS_WARNING) << "Failed to parse new-format protobuf message.";
1340         RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(allow_incomplete_logs_,
1341                                              kIncompleteLogError);
1342         RTC_PARSE_CHECK_OR_RETURN(false);
1343       }
1344       auto status = StoreParsedNewFormatEvent(event_stream);
1345       RTC_RETURN_IF_ERROR(status);
1346     }
1347   }
1348   return ParseStatus::Success();
1349 }
1350 
1351 template <typename T>
StoreFirstAndLastTimestamp(const std::vector<T> & v)1352 void ParsedRtcEventLog::StoreFirstAndLastTimestamp(const std::vector<T>& v) {
1353   if (v.empty())
1354     return;
1355   first_timestamp_ = std::min(first_timestamp_, v.front().log_time_us());
1356   last_timestamp_ = std::max(last_timestamp_, v.back().log_time_us());
1357 }
1358 
StoreParsedLegacyEvent(const rtclog::Event & event)1359 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedLegacyEvent(
1360     const rtclog::Event& event) {
1361   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1362   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1363   switch (event.type()) {
1364     case rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT: {
1365       auto config = GetVideoReceiveConfig(event);
1366       if (!config.ok())
1367         return config.status();
1368 
1369       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1370       int64_t timestamp_us = event.timestamp_us();
1371       video_recv_configs_.emplace_back(timestamp_us, config.value());
1372       incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
1373           RtpHeaderExtensionMap(config.value().rtp_extensions);
1374       incoming_rtp_extensions_maps_[config.value().rtx_ssrc] =
1375           RtpHeaderExtensionMap(config.value().rtp_extensions);
1376       break;
1377     }
1378     case rtclog::Event::VIDEO_SENDER_CONFIG_EVENT: {
1379       auto config = GetVideoSendConfig(event);
1380       if (!config.ok())
1381         return config.status();
1382 
1383       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1384       int64_t timestamp_us = event.timestamp_us();
1385       video_send_configs_.emplace_back(timestamp_us, config.value());
1386       outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
1387           RtpHeaderExtensionMap(config.value().rtp_extensions);
1388       outgoing_rtp_extensions_maps_[config.value().rtx_ssrc] =
1389           RtpHeaderExtensionMap(config.value().rtp_extensions);
1390       break;
1391     }
1392     case rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT: {
1393       auto config = GetAudioReceiveConfig(event);
1394       if (!config.ok())
1395         return config.status();
1396 
1397       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1398       int64_t timestamp_us = event.timestamp_us();
1399       audio_recv_configs_.emplace_back(timestamp_us, config.value());
1400       incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
1401           RtpHeaderExtensionMap(config.value().rtp_extensions);
1402       break;
1403     }
1404     case rtclog::Event::AUDIO_SENDER_CONFIG_EVENT: {
1405       auto config = GetAudioSendConfig(event);
1406       if (!config.ok())
1407         return config.status();
1408       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1409       int64_t timestamp_us = event.timestamp_us();
1410       audio_send_configs_.emplace_back(timestamp_us, config.value());
1411       outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
1412           RtpHeaderExtensionMap(config.value().rtp_extensions);
1413       break;
1414     }
1415     case rtclog::Event::RTP_EVENT: {
1416       PacketDirection direction;
1417       uint8_t header[IP_PACKET_SIZE];
1418       size_t header_length;
1419       size_t total_length;
1420       ParseStatus status = GetRtpHeader(event, &direction, header,
1421                                         &header_length, &total_length, nullptr);
1422       RTC_RETURN_IF_ERROR(status);
1423 
1424       uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(header + 8);
1425       const RtpHeaderExtensionMap* extension_map =
1426           GetRtpHeaderExtensionMap(direction, ssrc);
1427       RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
1428       RTPHeader parsed_header;
1429       rtp_parser.Parse(&parsed_header, extension_map, /*header_only*/ true);
1430 
1431       // Since we give the parser only a header, there is no way for it to know
1432       // the padding length. The best solution would be to log the padding
1433       // length in RTC event log. In absence of it, we assume the RTP packet to
1434       // contain only padding, if the padding bit is set.
1435       // TODO(webrtc:9730): Use a generic way to obtain padding length.
1436       if ((header[0] & 0x20) != 0)
1437         parsed_header.paddingLength = total_length - header_length;
1438 
1439       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1440       int64_t timestamp_us = event.timestamp_us();
1441       if (direction == kIncomingPacket) {
1442         incoming_rtp_packets_map_[parsed_header.ssrc].push_back(
1443             LoggedRtpPacketIncoming(timestamp_us, parsed_header, header_length,
1444                                     total_length));
1445       } else {
1446         outgoing_rtp_packets_map_[parsed_header.ssrc].push_back(
1447             LoggedRtpPacketOutgoing(timestamp_us, parsed_header, header_length,
1448                                     total_length));
1449       }
1450       break;
1451     }
1452     case rtclog::Event::RTCP_EVENT: {
1453       PacketDirection direction;
1454       uint8_t packet[IP_PACKET_SIZE];
1455       size_t total_length;
1456       auto status = GetRtcpPacket(event, &direction, packet, &total_length);
1457       RTC_RETURN_IF_ERROR(status);
1458       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1459       int64_t timestamp_us = event.timestamp_us();
1460       RTC_PARSE_CHECK_OR_RETURN_LE(total_length, IP_PACKET_SIZE);
1461       if (direction == kIncomingPacket) {
1462         // Currently incoming RTCP packets are logged twice, both for audio and
1463         // video. Only act on one of them. Compare against the previous parsed
1464         // incoming RTCP packet.
1465         if (total_length == last_incoming_rtcp_packet_length_ &&
1466             memcmp(last_incoming_rtcp_packet_, packet, total_length) == 0)
1467           break;
1468         incoming_rtcp_packets_.push_back(
1469             LoggedRtcpPacketIncoming(timestamp_us, packet, total_length));
1470         last_incoming_rtcp_packet_length_ = total_length;
1471         memcpy(last_incoming_rtcp_packet_, packet, total_length);
1472       } else {
1473         outgoing_rtcp_packets_.push_back(
1474             LoggedRtcpPacketOutgoing(timestamp_us, packet, total_length));
1475       }
1476       break;
1477     }
1478     case rtclog::Event::LOG_START: {
1479       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1480       int64_t timestamp_us = event.timestamp_us();
1481       start_log_events_.push_back(LoggedStartEvent(timestamp_us));
1482       break;
1483     }
1484     case rtclog::Event::LOG_END: {
1485       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1486       int64_t timestamp_us = event.timestamp_us();
1487       stop_log_events_.push_back(LoggedStopEvent(timestamp_us));
1488       break;
1489     }
1490     case rtclog::Event::AUDIO_PLAYOUT_EVENT: {
1491       auto status_or_value = GetAudioPlayout(event);
1492       RTC_RETURN_IF_ERROR(status_or_value.status());
1493       LoggedAudioPlayoutEvent playout_event = status_or_value.value();
1494       audio_playout_events_[playout_event.ssrc].push_back(playout_event);
1495       break;
1496     }
1497     case rtclog::Event::LOSS_BASED_BWE_UPDATE: {
1498       auto status_or_value = GetLossBasedBweUpdate(event);
1499       RTC_RETURN_IF_ERROR(status_or_value.status());
1500       bwe_loss_updates_.push_back(status_or_value.value());
1501       break;
1502     }
1503     case rtclog::Event::DELAY_BASED_BWE_UPDATE: {
1504       auto status_or_value = GetDelayBasedBweUpdate(event);
1505       RTC_RETURN_IF_ERROR(status_or_value.status());
1506       bwe_delay_updates_.push_back(status_or_value.value());
1507       break;
1508     }
1509     case rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT: {
1510       auto status_or_value = GetAudioNetworkAdaptation(event);
1511       RTC_RETURN_IF_ERROR(status_or_value.status());
1512       LoggedAudioNetworkAdaptationEvent ana_event = status_or_value.value();
1513       audio_network_adaptation_events_.push_back(ana_event);
1514       break;
1515     }
1516     case rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT: {
1517       auto status_or_value = GetBweProbeClusterCreated(event);
1518       RTC_RETURN_IF_ERROR(status_or_value.status());
1519       bwe_probe_cluster_created_events_.push_back(status_or_value.value());
1520       break;
1521     }
1522     case rtclog::Event::BWE_PROBE_RESULT_EVENT: {
1523       // Probe successes and failures are currently stored in the same proto
1524       // message, we are moving towards separate messages. Probe results
1525       // therefore need special treatment in the parser.
1526       RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
1527       RTC_PARSE_CHECK_OR_RETURN(event.probe_result().has_result());
1528       if (event.probe_result().result() == rtclog::BweProbeResult::SUCCESS) {
1529         auto status_or_value = GetBweProbeSuccess(event);
1530         RTC_RETURN_IF_ERROR(status_or_value.status());
1531         bwe_probe_success_events_.push_back(status_or_value.value());
1532       } else {
1533         auto status_or_value = GetBweProbeFailure(event);
1534         RTC_RETURN_IF_ERROR(status_or_value.status());
1535         bwe_probe_failure_events_.push_back(status_or_value.value());
1536       }
1537       break;
1538     }
1539     case rtclog::Event::ALR_STATE_EVENT: {
1540       auto status_or_value = GetAlrState(event);
1541       RTC_RETURN_IF_ERROR(status_or_value.status());
1542       alr_state_events_.push_back(status_or_value.value());
1543       break;
1544     }
1545     case rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG: {
1546       auto status_or_value = GetIceCandidatePairConfig(event);
1547       RTC_RETURN_IF_ERROR(status_or_value.status());
1548       ice_candidate_pair_configs_.push_back(status_or_value.value());
1549       break;
1550     }
1551     case rtclog::Event::ICE_CANDIDATE_PAIR_EVENT: {
1552       auto status_or_value = GetIceCandidatePairEvent(event);
1553       RTC_RETURN_IF_ERROR(status_or_value.status());
1554       ice_candidate_pair_events_.push_back(status_or_value.value());
1555       break;
1556     }
1557     case rtclog::Event::UNKNOWN_EVENT: {
1558       break;
1559     }
1560   }
1561   return ParseStatus::Success();
1562 }
1563 
1564 // 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) const1565 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::GetRtpHeader(
1566     const rtclog::Event& event,
1567     PacketDirection* incoming,
1568     uint8_t* header,
1569     size_t* header_length,
1570     size_t* total_length,
1571     int* probe_cluster_id) const {
1572   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1573   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::RTP_EVENT);
1574   RTC_PARSE_CHECK_OR_RETURN(event.has_rtp_packet());
1575   const rtclog::RtpPacket& rtp_packet = event.rtp_packet();
1576   // Get direction of packet.
1577   RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_incoming());
1578   if (incoming != nullptr) {
1579     *incoming = rtp_packet.incoming() ? kIncomingPacket : kOutgoingPacket;
1580   }
1581   // Get packet length.
1582   RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_packet_length());
1583   if (total_length != nullptr) {
1584     *total_length = rtp_packet.packet_length();
1585   }
1586   // Get header length.
1587   RTC_PARSE_CHECK_OR_RETURN(rtp_packet.has_header());
1588   if (header_length != nullptr) {
1589     *header_length = rtp_packet.header().size();
1590   }
1591   if (probe_cluster_id != nullptr) {
1592     if (rtp_packet.has_probe_cluster_id()) {
1593       *probe_cluster_id = rtp_packet.probe_cluster_id();
1594       RTC_PARSE_CHECK_OR_RETURN_NE(*probe_cluster_id,
1595                                    PacedPacketInfo::kNotAProbe);
1596     } else {
1597       *probe_cluster_id = PacedPacketInfo::kNotAProbe;
1598     }
1599   }
1600   // Get header contents.
1601   if (header != nullptr) {
1602     const size_t kMinRtpHeaderSize = 12;
1603     RTC_PARSE_CHECK_OR_RETURN_GE(rtp_packet.header().size(), kMinRtpHeaderSize);
1604     RTC_PARSE_CHECK_OR_RETURN_LE(rtp_packet.header().size(),
1605                                  static_cast<size_t>(IP_PACKET_SIZE));
1606     memcpy(header, rtp_packet.header().data(), rtp_packet.header().size());
1607   }
1608   return ParseStatus::Success();
1609 }
1610 
GetRtpHeaderExtensionMap(PacketDirection direction,uint32_t ssrc)1611 const RtpHeaderExtensionMap* ParsedRtcEventLog::GetRtpHeaderExtensionMap(
1612     PacketDirection direction,
1613     uint32_t ssrc) {
1614   auto& extensions_maps = direction == PacketDirection::kIncomingPacket
1615                               ? incoming_rtp_extensions_maps_
1616                               : outgoing_rtp_extensions_maps_;
1617   auto it = extensions_maps.find(ssrc);
1618   if (it != extensions_maps.end()) {
1619     return &(it->second);
1620   }
1621   if (parse_unconfigured_header_extensions_ ==
1622       UnconfiguredHeaderExtensions::kAttemptWebrtcDefaultConfig) {
1623     RTC_LOG(LS_WARNING) << "Using default header extension map for SSRC "
1624                         << ssrc;
1625     extensions_maps.insert(std::make_pair(ssrc, default_extension_map_));
1626     return &default_extension_map_;
1627   }
1628   RTC_LOG(LS_WARNING) << "Not parsing header extensions for SSRC " << ssrc
1629                       << ". No header extension map found.";
1630   return nullptr;
1631 }
1632 
1633 // 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) const1634 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::GetRtcpPacket(
1635     const rtclog::Event& event,
1636     PacketDirection* incoming,
1637     uint8_t* packet,
1638     size_t* length) const {
1639   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1640   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::RTCP_EVENT);
1641   RTC_PARSE_CHECK_OR_RETURN(event.has_rtcp_packet());
1642   const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet();
1643   // Get direction of packet.
1644   RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_incoming());
1645   if (incoming != nullptr) {
1646     *incoming = rtcp_packet.incoming() ? kIncomingPacket : kOutgoingPacket;
1647   }
1648   // Get packet length.
1649   RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_packet_data());
1650   if (length != nullptr) {
1651     *length = rtcp_packet.packet_data().size();
1652   }
1653   // Get packet contents.
1654   if (packet != nullptr) {
1655     RTC_PARSE_CHECK_OR_RETURN_LE(rtcp_packet.packet_data().size(),
1656                                  static_cast<unsigned>(IP_PACKET_SIZE));
1657     memcpy(packet, rtcp_packet.packet_data().data(),
1658            rtcp_packet.packet_data().size());
1659   }
1660   return ParseStatus::Success();
1661 }
1662 
1663 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
GetVideoReceiveConfig(const rtclog::Event & event) const1664 ParsedRtcEventLog::GetVideoReceiveConfig(const rtclog::Event& event) const {
1665   rtclog::StreamConfig config;
1666   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1667   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1668                                rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
1669   RTC_PARSE_CHECK_OR_RETURN(event.has_video_receiver_config());
1670   const rtclog::VideoReceiveConfig& receiver_config =
1671       event.video_receiver_config();
1672   // Get SSRCs.
1673   RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remote_ssrc());
1674   config.remote_ssrc = receiver_config.remote_ssrc();
1675   RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_local_ssrc());
1676   config.local_ssrc = receiver_config.local_ssrc();
1677   config.rtx_ssrc = 0;
1678   // Get RTCP settings.
1679   RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_rtcp_mode());
1680   config.rtcp_mode = GetRuntimeRtcpMode(receiver_config.rtcp_mode());
1681   RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remb());
1682   config.remb = receiver_config.remb();
1683 
1684   // Get RTX map.
1685   std::map<uint32_t, const rtclog::RtxConfig> rtx_map;
1686   for (int i = 0; i < receiver_config.rtx_map_size(); i++) {
1687     const rtclog::RtxMap& map = receiver_config.rtx_map(i);
1688     RTC_PARSE_CHECK_OR_RETURN(map.has_payload_type());
1689     RTC_PARSE_CHECK_OR_RETURN(map.has_config());
1690     RTC_PARSE_CHECK_OR_RETURN(map.config().has_rtx_ssrc());
1691     RTC_PARSE_CHECK_OR_RETURN(map.config().has_rtx_payload_type());
1692     rtx_map.insert(std::make_pair(map.payload_type(), map.config()));
1693   }
1694 
1695   // Get header extensions.
1696   auto status = GetHeaderExtensions(&config.rtp_extensions,
1697                                     receiver_config.header_extensions());
1698   RTC_RETURN_IF_ERROR(status);
1699 
1700   // Get decoders.
1701   config.codecs.clear();
1702   for (int i = 0; i < receiver_config.decoders_size(); i++) {
1703     RTC_PARSE_CHECK_OR_RETURN(receiver_config.decoders(i).has_name());
1704     RTC_PARSE_CHECK_OR_RETURN(receiver_config.decoders(i).has_payload_type());
1705     int rtx_payload_type = 0;
1706     auto rtx_it = rtx_map.find(receiver_config.decoders(i).payload_type());
1707     if (rtx_it != rtx_map.end()) {
1708       rtx_payload_type = rtx_it->second.rtx_payload_type();
1709       if (config.rtx_ssrc != 0 &&
1710           config.rtx_ssrc != rtx_it->second.rtx_ssrc()) {
1711         RTC_LOG(LS_WARNING)
1712             << "RtcEventLog protobuf contained different SSRCs for "
1713                "different received RTX payload types. Will only use "
1714                "rtx_ssrc = "
1715             << config.rtx_ssrc << ".";
1716       } else {
1717         config.rtx_ssrc = rtx_it->second.rtx_ssrc();
1718       }
1719     }
1720     config.codecs.emplace_back(receiver_config.decoders(i).name(),
1721                                receiver_config.decoders(i).payload_type(),
1722                                rtx_payload_type);
1723   }
1724   return config;
1725 }
1726 
1727 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
GetVideoSendConfig(const rtclog::Event & event) const1728 ParsedRtcEventLog::GetVideoSendConfig(const rtclog::Event& event) const {
1729   rtclog::StreamConfig config;
1730   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1731   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1732                                rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
1733   RTC_PARSE_CHECK_OR_RETURN(event.has_video_sender_config());
1734   const rtclog::VideoSendConfig& sender_config = event.video_sender_config();
1735 
1736   // Get SSRCs.
1737   // VideoSendStreamConfig no longer stores multiple SSRCs. If you are
1738   // analyzing a very old log, try building the parser from the same
1739   // WebRTC version.
1740   RTC_PARSE_CHECK_OR_RETURN_EQ(sender_config.ssrcs_size(), 1);
1741   config.local_ssrc = sender_config.ssrcs(0);
1742   RTC_PARSE_CHECK_OR_RETURN_LE(sender_config.rtx_ssrcs_size(), 1);
1743   if (sender_config.rtx_ssrcs_size() == 1) {
1744     config.rtx_ssrc = sender_config.rtx_ssrcs(0);
1745   }
1746 
1747   // Get header extensions.
1748   auto status = GetHeaderExtensions(&config.rtp_extensions,
1749                                     sender_config.header_extensions());
1750   RTC_RETURN_IF_ERROR(status);
1751 
1752   // Get the codec.
1753   RTC_PARSE_CHECK_OR_RETURN(sender_config.has_encoder());
1754   RTC_PARSE_CHECK_OR_RETURN(sender_config.encoder().has_name());
1755   RTC_PARSE_CHECK_OR_RETURN(sender_config.encoder().has_payload_type());
1756   config.codecs.emplace_back(
1757       sender_config.encoder().name(), sender_config.encoder().payload_type(),
1758       sender_config.has_rtx_payload_type() ? sender_config.rtx_payload_type()
1759                                            : 0);
1760   return config;
1761 }
1762 
1763 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
GetAudioReceiveConfig(const rtclog::Event & event) const1764 ParsedRtcEventLog::GetAudioReceiveConfig(const rtclog::Event& event) const {
1765   rtclog::StreamConfig config;
1766   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1767   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1768                                rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT);
1769   RTC_PARSE_CHECK_OR_RETURN(event.has_audio_receiver_config());
1770   const rtclog::AudioReceiveConfig& receiver_config =
1771       event.audio_receiver_config();
1772   // Get SSRCs.
1773   RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_remote_ssrc());
1774   config.remote_ssrc = receiver_config.remote_ssrc();
1775   RTC_PARSE_CHECK_OR_RETURN(receiver_config.has_local_ssrc());
1776   config.local_ssrc = receiver_config.local_ssrc();
1777   // Get header extensions.
1778   auto status = GetHeaderExtensions(&config.rtp_extensions,
1779                                     receiver_config.header_extensions());
1780   RTC_RETURN_IF_ERROR(status);
1781 
1782   return config;
1783 }
1784 
1785 ParsedRtcEventLog::ParseStatusOr<rtclog::StreamConfig>
GetAudioSendConfig(const rtclog::Event & event) const1786 ParsedRtcEventLog::GetAudioSendConfig(const rtclog::Event& event) const {
1787   rtclog::StreamConfig config;
1788   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1789   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1790                                rtclog::Event::AUDIO_SENDER_CONFIG_EVENT);
1791   RTC_PARSE_CHECK_OR_RETURN(event.has_audio_sender_config());
1792   const rtclog::AudioSendConfig& sender_config = event.audio_sender_config();
1793   // Get SSRCs.
1794   RTC_PARSE_CHECK_OR_RETURN(sender_config.has_ssrc());
1795   config.local_ssrc = sender_config.ssrc();
1796   // Get header extensions.
1797   auto status = GetHeaderExtensions(&config.rtp_extensions,
1798                                     sender_config.header_extensions());
1799   RTC_RETURN_IF_ERROR(status);
1800 
1801   return config;
1802 }
1803 
1804 ParsedRtcEventLog::ParseStatusOr<LoggedAudioPlayoutEvent>
GetAudioPlayout(const rtclog::Event & event) const1805 ParsedRtcEventLog::GetAudioPlayout(const rtclog::Event& event) const {
1806   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1807   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1808                                rtclog::Event::AUDIO_PLAYOUT_EVENT);
1809   RTC_PARSE_CHECK_OR_RETURN(event.has_audio_playout_event());
1810   const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event();
1811   LoggedAudioPlayoutEvent res;
1812   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1813   res.timestamp_us = event.timestamp_us();
1814   RTC_PARSE_CHECK_OR_RETURN(playout_event.has_local_ssrc());
1815   res.ssrc = playout_event.local_ssrc();
1816   return res;
1817 }
1818 
1819 ParsedRtcEventLog::ParseStatusOr<LoggedBweLossBasedUpdate>
GetLossBasedBweUpdate(const rtclog::Event & event) const1820 ParsedRtcEventLog::GetLossBasedBweUpdate(const rtclog::Event& event) const {
1821   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1822   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1823                                rtclog::Event::LOSS_BASED_BWE_UPDATE);
1824   RTC_PARSE_CHECK_OR_RETURN(event.has_loss_based_bwe_update());
1825   const rtclog::LossBasedBweUpdate& loss_event = event.loss_based_bwe_update();
1826 
1827   LoggedBweLossBasedUpdate bwe_update;
1828   RTC_CHECK(event.has_timestamp_us());
1829   bwe_update.timestamp_us = event.timestamp_us();
1830   RTC_PARSE_CHECK_OR_RETURN(loss_event.has_bitrate_bps());
1831   bwe_update.bitrate_bps = loss_event.bitrate_bps();
1832   RTC_PARSE_CHECK_OR_RETURN(loss_event.has_fraction_loss());
1833   bwe_update.fraction_lost = loss_event.fraction_loss();
1834   RTC_PARSE_CHECK_OR_RETURN(loss_event.has_total_packets());
1835   bwe_update.expected_packets = loss_event.total_packets();
1836   return bwe_update;
1837 }
1838 
1839 ParsedRtcEventLog::ParseStatusOr<LoggedBweDelayBasedUpdate>
GetDelayBasedBweUpdate(const rtclog::Event & event) const1840 ParsedRtcEventLog::GetDelayBasedBweUpdate(const rtclog::Event& event) const {
1841   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1842   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1843                                rtclog::Event::DELAY_BASED_BWE_UPDATE);
1844   RTC_PARSE_CHECK_OR_RETURN(event.has_delay_based_bwe_update());
1845   const rtclog::DelayBasedBweUpdate& delay_event =
1846       event.delay_based_bwe_update();
1847 
1848   LoggedBweDelayBasedUpdate res;
1849   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1850   res.timestamp_us = event.timestamp_us();
1851   RTC_PARSE_CHECK_OR_RETURN(delay_event.has_bitrate_bps());
1852   res.bitrate_bps = delay_event.bitrate_bps();
1853   RTC_PARSE_CHECK_OR_RETURN(delay_event.has_detector_state());
1854   res.detector_state = GetRuntimeDetectorState(delay_event.detector_state());
1855   return res;
1856 }
1857 
1858 ParsedRtcEventLog::ParseStatusOr<LoggedAudioNetworkAdaptationEvent>
GetAudioNetworkAdaptation(const rtclog::Event & event) const1859 ParsedRtcEventLog::GetAudioNetworkAdaptation(const rtclog::Event& event) const {
1860   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1861   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1862                                rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
1863   RTC_PARSE_CHECK_OR_RETURN(event.has_audio_network_adaptation());
1864   const rtclog::AudioNetworkAdaptation& ana_event =
1865       event.audio_network_adaptation();
1866 
1867   LoggedAudioNetworkAdaptationEvent res;
1868   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1869   res.timestamp_us = event.timestamp_us();
1870   if (ana_event.has_bitrate_bps())
1871     res.config.bitrate_bps = ana_event.bitrate_bps();
1872   if (ana_event.has_enable_fec())
1873     res.config.enable_fec = ana_event.enable_fec();
1874   if (ana_event.has_enable_dtx())
1875     res.config.enable_dtx = ana_event.enable_dtx();
1876   if (ana_event.has_frame_length_ms())
1877     res.config.frame_length_ms = ana_event.frame_length_ms();
1878   if (ana_event.has_num_channels())
1879     res.config.num_channels = ana_event.num_channels();
1880   if (ana_event.has_uplink_packet_loss_fraction())
1881     res.config.uplink_packet_loss_fraction =
1882         ana_event.uplink_packet_loss_fraction();
1883   return res;
1884 }
1885 
1886 ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeClusterCreatedEvent>
GetBweProbeClusterCreated(const rtclog::Event & event) const1887 ParsedRtcEventLog::GetBweProbeClusterCreated(const rtclog::Event& event) const {
1888   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1889   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1890                                rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
1891   RTC_PARSE_CHECK_OR_RETURN(event.has_probe_cluster());
1892   const rtclog::BweProbeCluster& pcc_event = event.probe_cluster();
1893   LoggedBweProbeClusterCreatedEvent res;
1894   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1895   res.timestamp_us = event.timestamp_us();
1896   RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_id());
1897   res.id = pcc_event.id();
1898   RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_bitrate_bps());
1899   res.bitrate_bps = pcc_event.bitrate_bps();
1900   RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_min_packets());
1901   res.min_packets = pcc_event.min_packets();
1902   RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_min_bytes());
1903   res.min_bytes = pcc_event.min_bytes();
1904   return res;
1905 }
1906 
1907 ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeFailureEvent>
GetBweProbeFailure(const rtclog::Event & event) const1908 ParsedRtcEventLog::GetBweProbeFailure(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_NE(pr_event.result(),
1916                                rtclog::BweProbeResult::SUCCESS);
1917 
1918   LoggedBweProbeFailureEvent 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_result());
1924   if (pr_event.result() ==
1925       rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL) {
1926     res.failure_reason = ProbeFailureReason::kInvalidSendReceiveInterval;
1927   } else if (pr_event.result() ==
1928              rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO) {
1929     res.failure_reason = ProbeFailureReason::kInvalidSendReceiveRatio;
1930   } else if (pr_event.result() == rtclog::BweProbeResult::TIMEOUT) {
1931     res.failure_reason = ProbeFailureReason::kTimeout;
1932   } else {
1933     RTC_NOTREACHED();
1934   }
1935   RTC_PARSE_CHECK_OR_RETURN(!pr_event.has_bitrate_bps());
1936 
1937   return res;
1938 }
1939 
1940 ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeSuccessEvent>
GetBweProbeSuccess(const rtclog::Event & event) const1941 ParsedRtcEventLog::GetBweProbeSuccess(const rtclog::Event& event) const {
1942   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1943   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(),
1944                                rtclog::Event::BWE_PROBE_RESULT_EVENT);
1945   RTC_PARSE_CHECK_OR_RETURN(event.has_probe_result());
1946   const rtclog::BweProbeResult& pr_event = event.probe_result();
1947   RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
1948   RTC_PARSE_CHECK_OR_RETURN_EQ(pr_event.result(),
1949                                rtclog::BweProbeResult::SUCCESS);
1950 
1951   LoggedBweProbeSuccessEvent res;
1952   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1953   res.timestamp_us = event.timestamp_us();
1954   RTC_PARSE_CHECK_OR_RETURN(pr_event.has_id());
1955   res.id = pr_event.id();
1956   RTC_PARSE_CHECK_OR_RETURN(pr_event.has_bitrate_bps());
1957   res.bitrate_bps = pr_event.bitrate_bps();
1958 
1959   return res;
1960 }
1961 
1962 ParsedRtcEventLog::ParseStatusOr<LoggedAlrStateEvent>
GetAlrState(const rtclog::Event & event) const1963 ParsedRtcEventLog::GetAlrState(const rtclog::Event& event) const {
1964   RTC_PARSE_CHECK_OR_RETURN(event.has_type());
1965   RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::ALR_STATE_EVENT);
1966   RTC_PARSE_CHECK_OR_RETURN(event.has_alr_state());
1967   const rtclog::AlrState& alr_event = event.alr_state();
1968   LoggedAlrStateEvent res;
1969   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
1970   res.timestamp_us = event.timestamp_us();
1971   RTC_PARSE_CHECK_OR_RETURN(alr_event.has_in_alr());
1972   res.in_alr = alr_event.in_alr();
1973 
1974   return res;
1975 }
1976 
1977 ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairConfig>
GetIceCandidatePairConfig(const rtclog::Event & rtc_event) const1978 ParsedRtcEventLog::GetIceCandidatePairConfig(
1979     const rtclog::Event& rtc_event) const {
1980   RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_type());
1981   RTC_PARSE_CHECK_OR_RETURN_EQ(rtc_event.type(),
1982                                rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
1983   LoggedIceCandidatePairConfig res;
1984   const rtclog::IceCandidatePairConfig& config =
1985       rtc_event.ice_candidate_pair_config();
1986   RTC_CHECK(rtc_event.has_timestamp_us());
1987   res.timestamp_us = rtc_event.timestamp_us();
1988   RTC_PARSE_CHECK_OR_RETURN(config.has_config_type());
1989   res.type = GetRuntimeIceCandidatePairConfigType(config.config_type());
1990   RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_id());
1991   res.candidate_pair_id = config.candidate_pair_id();
1992   RTC_PARSE_CHECK_OR_RETURN(config.has_local_candidate_type());
1993   res.local_candidate_type =
1994       GetRuntimeIceCandidateType(config.local_candidate_type());
1995   RTC_PARSE_CHECK_OR_RETURN(config.has_local_relay_protocol());
1996   res.local_relay_protocol =
1997       GetRuntimeIceCandidatePairProtocol(config.local_relay_protocol());
1998   RTC_PARSE_CHECK_OR_RETURN(config.has_local_network_type());
1999   res.local_network_type =
2000       GetRuntimeIceCandidateNetworkType(config.local_network_type());
2001   RTC_PARSE_CHECK_OR_RETURN(config.has_local_address_family());
2002   res.local_address_family =
2003       GetRuntimeIceCandidatePairAddressFamily(config.local_address_family());
2004   RTC_PARSE_CHECK_OR_RETURN(config.has_remote_candidate_type());
2005   res.remote_candidate_type =
2006       GetRuntimeIceCandidateType(config.remote_candidate_type());
2007   RTC_PARSE_CHECK_OR_RETURN(config.has_remote_address_family());
2008   res.remote_address_family =
2009       GetRuntimeIceCandidatePairAddressFamily(config.remote_address_family());
2010   RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_protocol());
2011   res.candidate_pair_protocol =
2012       GetRuntimeIceCandidatePairProtocol(config.candidate_pair_protocol());
2013   return res;
2014 }
2015 
2016 ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairEvent>
GetIceCandidatePairEvent(const rtclog::Event & rtc_event) const2017 ParsedRtcEventLog::GetIceCandidatePairEvent(
2018     const rtclog::Event& rtc_event) const {
2019   RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_type());
2020   RTC_PARSE_CHECK_OR_RETURN_EQ(rtc_event.type(),
2021                                rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
2022   LoggedIceCandidatePairEvent res;
2023   const rtclog::IceCandidatePairEvent& event =
2024       rtc_event.ice_candidate_pair_event();
2025   RTC_CHECK(rtc_event.has_timestamp_us());
2026   res.timestamp_us = rtc_event.timestamp_us();
2027   RTC_PARSE_CHECK_OR_RETURN(event.has_event_type());
2028   res.type = GetRuntimeIceCandidatePairEventType(event.event_type());
2029   RTC_PARSE_CHECK_OR_RETURN(event.has_candidate_pair_id());
2030   res.candidate_pair_id = event.candidate_pair_id();
2031   // transaction_id is not supported by rtclog::Event
2032   res.transaction_id = 0;
2033   return res;
2034 }
2035 
2036 // Returns the MediaType for registered SSRCs. Search from the end to use last
2037 // registered types first.
GetMediaType(uint32_t ssrc,PacketDirection direction) const2038 ParsedRtcEventLog::MediaType ParsedRtcEventLog::GetMediaType(
2039     uint32_t ssrc,
2040     PacketDirection direction) const {
2041   if (direction == kIncomingPacket) {
2042     if (std::find(incoming_video_ssrcs_.begin(), incoming_video_ssrcs_.end(),
2043                   ssrc) != incoming_video_ssrcs_.end()) {
2044       return MediaType::VIDEO;
2045     }
2046     if (std::find(incoming_audio_ssrcs_.begin(), incoming_audio_ssrcs_.end(),
2047                   ssrc) != incoming_audio_ssrcs_.end()) {
2048       return MediaType::AUDIO;
2049     }
2050   } else {
2051     if (std::find(outgoing_video_ssrcs_.begin(), outgoing_video_ssrcs_.end(),
2052                   ssrc) != outgoing_video_ssrcs_.end()) {
2053       return MediaType::VIDEO;
2054     }
2055     if (std::find(outgoing_audio_ssrcs_.begin(), outgoing_audio_ssrcs_.end(),
2056                   ssrc) != outgoing_audio_ssrcs_.end()) {
2057       return MediaType::AUDIO;
2058     }
2059   }
2060   return MediaType::ANY;
2061 }
2062 
GetRouteChanges() const2063 std::vector<InferredRouteChangeEvent> ParsedRtcEventLog::GetRouteChanges()
2064     const {
2065   std::vector<InferredRouteChangeEvent> route_changes;
2066   for (auto& candidate : ice_candidate_pair_configs()) {
2067     if (candidate.type == IceCandidatePairConfigType::kSelected) {
2068       InferredRouteChangeEvent route;
2069       route.route_id = candidate.candidate_pair_id;
2070       route.log_time = Timestamp::Millis(candidate.log_time_ms());
2071 
2072       route.send_overhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead;
2073       if (candidate.remote_address_family ==
2074           IceCandidatePairAddressFamily::kIpv6)
2075         route.send_overhead += kIpv6Overhead - kIpv4Overhead;
2076       if (candidate.remote_candidate_type != IceCandidateType::kLocal)
2077         route.send_overhead += kStunOverhead;
2078       route.return_overhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead;
2079       if (candidate.remote_address_family ==
2080           IceCandidatePairAddressFamily::kIpv6)
2081         route.return_overhead += kIpv6Overhead - kIpv4Overhead;
2082       if (candidate.remote_candidate_type != IceCandidateType::kLocal)
2083         route.return_overhead += kStunOverhead;
2084       route_changes.push_back(route);
2085     }
2086   }
2087   return route_changes;
2088 }
2089 
GetPacketInfos(PacketDirection direction) const2090 std::vector<LoggedPacketInfo> ParsedRtcEventLog::GetPacketInfos(
2091     PacketDirection direction) const {
2092   std::map<uint32_t, MediaStreamInfo> streams;
2093   if (direction == PacketDirection::kIncomingPacket) {
2094     AddRecvStreamInfos(&streams, audio_recv_configs(), LoggedMediaType::kAudio);
2095     AddRecvStreamInfos(&streams, video_recv_configs(), LoggedMediaType::kVideo);
2096   } else if (direction == PacketDirection::kOutgoingPacket) {
2097     AddSendStreamInfos(&streams, audio_send_configs(), LoggedMediaType::kAudio);
2098     AddSendStreamInfos(&streams, video_send_configs(), LoggedMediaType::kVideo);
2099   }
2100 
2101   std::vector<OverheadChangeEvent> overheads =
2102       GetOverheadChangingEvents(GetRouteChanges(), direction);
2103   auto overhead_iter = overheads.begin();
2104   std::vector<LoggedPacketInfo> packets;
2105   std::map<int64_t, size_t> indices;
2106   uint16_t current_overhead = kDefaultOverhead;
2107   Timestamp last_log_time = Timestamp::Zero();
2108   SequenceNumberUnwrapper seq_num_unwrapper;
2109 
2110   auto advance_time = [&](Timestamp new_log_time) {
2111     if (overhead_iter != overheads.end() &&
2112         new_log_time >= overhead_iter->timestamp) {
2113       current_overhead = overhead_iter->overhead;
2114       ++overhead_iter;
2115     }
2116     // If we have a large time delta, it can be caused by a gap in logging,
2117     // therefore we don't want to match up sequence numbers as we might have had
2118     // a wraparound.
2119     if (new_log_time - last_log_time > TimeDelta::Seconds(30)) {
2120       seq_num_unwrapper = SequenceNumberUnwrapper();
2121       indices.clear();
2122     }
2123     RTC_DCHECK(new_log_time >= last_log_time);
2124     last_log_time = new_log_time;
2125   };
2126 
2127   auto rtp_handler = [&](const LoggedRtpPacket& rtp) {
2128     advance_time(Timestamp::Millis(rtp.log_time_ms()));
2129     MediaStreamInfo* stream = &streams[rtp.header.ssrc];
2130     Timestamp capture_time = Timestamp::MinusInfinity();
2131     if (!stream->rtx) {
2132       // RTX copy the timestamp of the retransmitted packets. This means that
2133       // RTX streams don't have a unique clock offset and frequency, so
2134       // the RTP timstamps can't be unwrapped.
2135 
2136       // Add an offset to avoid |capture_ticks| to become negative in the case
2137       // of reordering.
2138       constexpr int64_t kStartingCaptureTimeTicks = 90 * 48 * 1000;
2139       int64_t capture_ticks =
2140           kStartingCaptureTimeTicks +
2141           stream->unwrap_capture_ticks.Unwrap(rtp.header.timestamp);
2142       // TODO(srte): Use logged sample rate when it is added to the format.
2143       capture_time = Timestamp::Seconds(
2144           capture_ticks /
2145           (stream->media_type == LoggedMediaType::kAudio ? 48000.0 : 90000.0));
2146     }
2147     LoggedPacketInfo logged(rtp, stream->media_type, stream->rtx, capture_time);
2148     logged.overhead = current_overhead;
2149     if (logged.has_transport_seq_no) {
2150       logged.log_feedback_time = Timestamp::PlusInfinity();
2151       int64_t unwrapped_seq_num =
2152           seq_num_unwrapper.Unwrap(logged.transport_seq_no);
2153       if (indices.find(unwrapped_seq_num) != indices.end()) {
2154         auto prev = packets[indices[unwrapped_seq_num]];
2155         RTC_LOG(LS_WARNING)
2156             << "Repeated sent packet sequence number: " << unwrapped_seq_num
2157             << " Packet time:" << prev.log_packet_time.seconds() << "s vs "
2158             << logged.log_packet_time.seconds()
2159             << "s at:" << rtp.log_time_ms() / 1000;
2160       }
2161       indices[unwrapped_seq_num] = packets.size();
2162     }
2163     packets.push_back(logged);
2164   };
2165 
2166   Timestamp feedback_base_time = Timestamp::MinusInfinity();
2167   absl::optional<int64_t> last_feedback_base_time_us;
2168 
2169   auto feedback_handler =
2170       [&](const LoggedRtcpPacketTransportFeedback& logged_rtcp) {
2171         auto log_feedback_time = Timestamp::Millis(logged_rtcp.log_time_ms());
2172         advance_time(log_feedback_time);
2173         const auto& feedback = logged_rtcp.transport_feedback;
2174         // Add timestamp deltas to a local time base selected on first packet
2175         // arrival. This won't be the true time base, but makes it easier to
2176         // manually inspect time stamps.
2177         if (!last_feedback_base_time_us) {
2178           feedback_base_time = log_feedback_time;
2179         } else {
2180           feedback_base_time += TimeDelta::Micros(
2181               feedback.GetBaseDeltaUs(*last_feedback_base_time_us));
2182         }
2183         last_feedback_base_time_us = feedback.GetBaseTimeUs();
2184 
2185         std::vector<LoggedPacketInfo*> packet_feedbacks;
2186         packet_feedbacks.reserve(feedback.GetAllPackets().size());
2187         Timestamp receive_timestamp = feedback_base_time;
2188         std::vector<int64_t> unknown_seq_nums;
2189         for (const auto& packet : feedback.GetAllPackets()) {
2190           int64_t unwrapped_seq_num =
2191               seq_num_unwrapper.Unwrap(packet.sequence_number());
2192           auto it = indices.find(unwrapped_seq_num);
2193           if (it == indices.end()) {
2194             unknown_seq_nums.push_back(unwrapped_seq_num);
2195             continue;
2196           }
2197           LoggedPacketInfo* sent = &packets[it->second];
2198           if (log_feedback_time - sent->log_packet_time >
2199               TimeDelta::Seconds(60)) {
2200             RTC_LOG(LS_WARNING)
2201                 << "Received very late feedback, possibly due to wraparound.";
2202             continue;
2203           }
2204           if (packet.received()) {
2205             receive_timestamp += TimeDelta::Micros(packet.delta_us());
2206             if (sent->reported_recv_time.IsInfinite()) {
2207               sent->reported_recv_time =
2208                   Timestamp::Millis(receive_timestamp.ms());
2209               sent->log_feedback_time = log_feedback_time;
2210             }
2211           } else {
2212             if (sent->reported_recv_time.IsInfinite() &&
2213                 sent->log_feedback_time.IsInfinite()) {
2214               sent->reported_recv_time = Timestamp::PlusInfinity();
2215               sent->log_feedback_time = log_feedback_time;
2216             }
2217           }
2218           packet_feedbacks.push_back(sent);
2219         }
2220         if (!unknown_seq_nums.empty()) {
2221           RTC_LOG(LS_WARNING)
2222               << "Received feedback for unknown packets: "
2223               << unknown_seq_nums.front() << " - " << unknown_seq_nums.back();
2224         }
2225         if (packet_feedbacks.empty())
2226           return;
2227         LoggedPacketInfo* last = packet_feedbacks.back();
2228         last->last_in_feedback = true;
2229         for (LoggedPacketInfo* fb : packet_feedbacks) {
2230           if (direction == PacketDirection::kOutgoingPacket) {
2231             fb->feedback_hold_duration =
2232                 last->reported_recv_time - fb->reported_recv_time;
2233           } else {
2234             fb->feedback_hold_duration =
2235                 log_feedback_time - fb->log_packet_time;
2236           }
2237         }
2238       };
2239 
2240   RtcEventProcessor process;
2241   for (const auto& rtp_packets : rtp_packets_by_ssrc(direction)) {
2242     process.AddEvents(rtp_packets.packet_view, rtp_handler);
2243   }
2244   if (direction == PacketDirection::kOutgoingPacket) {
2245     process.AddEvents(incoming_transport_feedback_, feedback_handler);
2246   } else {
2247     process.AddEvents(outgoing_transport_feedback_, feedback_handler);
2248   }
2249   process.ProcessEventsInOrder();
2250   return packets;
2251 }
2252 
GetIceCandidates() const2253 std::vector<LoggedIceCandidatePairConfig> ParsedRtcEventLog::GetIceCandidates()
2254     const {
2255   std::vector<LoggedIceCandidatePairConfig> candidates;
2256   std::set<uint32_t> added;
2257   for (auto& candidate : ice_candidate_pair_configs()) {
2258     if (added.find(candidate.candidate_pair_id) == added.end()) {
2259       candidates.push_back(candidate);
2260       added.insert(candidate.candidate_pair_id);
2261     }
2262   }
2263   return candidates;
2264 }
2265 
GetIceEvents() const2266 std::vector<LoggedIceEvent> ParsedRtcEventLog::GetIceEvents() const {
2267   using CheckType = IceCandidatePairEventType;
2268   using ConfigType = IceCandidatePairConfigType;
2269   using Combined = LoggedIceEventType;
2270   std::map<CheckType, Combined> check_map(
2271       {{CheckType::kCheckSent, Combined::kCheckSent},
2272        {CheckType::kCheckReceived, Combined::kCheckReceived},
2273        {CheckType::kCheckResponseSent, Combined::kCheckResponseSent},
2274        {CheckType::kCheckResponseReceived, Combined::kCheckResponseReceived}});
2275   std::map<ConfigType, Combined> config_map(
2276       {{ConfigType::kAdded, Combined::kAdded},
2277        {ConfigType::kUpdated, Combined::kUpdated},
2278        {ConfigType::kDestroyed, Combined::kDestroyed},
2279        {ConfigType::kSelected, Combined::kSelected}});
2280   std::vector<LoggedIceEvent> log_events;
2281   auto handle_check = [&](const LoggedIceCandidatePairEvent& check) {
2282     log_events.push_back(LoggedIceEvent{check.candidate_pair_id,
2283                                         Timestamp::Millis(check.log_time_ms()),
2284                                         check_map[check.type]});
2285   };
2286   auto handle_config = [&](const LoggedIceCandidatePairConfig& conf) {
2287     log_events.push_back(LoggedIceEvent{conf.candidate_pair_id,
2288                                         Timestamp::Millis(conf.log_time_ms()),
2289                                         config_map[conf.type]});
2290   };
2291   RtcEventProcessor process;
2292   process.AddEvents(ice_candidate_pair_events(), handle_check);
2293   process.AddEvents(ice_candidate_pair_configs(), handle_config);
2294   process.ProcessEventsInOrder();
2295   return log_events;
2296 }
2297 
GetNetworkTrace(const ParsedRtcEventLog & parsed_log)2298 const std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
2299     const ParsedRtcEventLog& parsed_log) {
2300   std::vector<MatchedSendArrivalTimes> rtp_rtcp_matched;
2301   for (auto& packet :
2302        parsed_log.GetPacketInfos(PacketDirection::kOutgoingPacket)) {
2303     if (packet.log_feedback_time.IsFinite()) {
2304       rtp_rtcp_matched.emplace_back(packet.log_feedback_time.ms(),
2305                                     packet.log_packet_time.ms(),
2306                                     packet.reported_recv_time.ms_or(
2307                                         MatchedSendArrivalTimes::kNotReceived),
2308                                     packet.size);
2309     }
2310   }
2311   return rtp_rtcp_matched;
2312 }
2313 
2314 // Helper functions for new format start here
StoreParsedNewFormatEvent(const rtclog2::EventStream & stream)2315 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedNewFormatEvent(
2316     const rtclog2::EventStream& stream) {
2317   RTC_DCHECK_EQ(stream.stream_size(), 0);  // No legacy format event.
2318 
2319   RTC_DCHECK_EQ(
2320       stream.incoming_rtp_packets_size() + stream.outgoing_rtp_packets_size() +
2321           stream.incoming_rtcp_packets_size() +
2322           stream.outgoing_rtcp_packets_size() +
2323           stream.audio_playout_events_size() + stream.begin_log_events_size() +
2324           stream.end_log_events_size() + stream.loss_based_bwe_updates_size() +
2325           stream.delay_based_bwe_updates_size() +
2326           stream.dtls_transport_state_events_size() +
2327           stream.dtls_writable_states_size() +
2328           stream.audio_network_adaptations_size() +
2329           stream.probe_clusters_size() + stream.probe_success_size() +
2330           stream.probe_failure_size() + stream.alr_states_size() +
2331           stream.route_changes_size() + stream.remote_estimates_size() +
2332           stream.ice_candidate_configs_size() +
2333           stream.ice_candidate_events_size() +
2334           stream.audio_recv_stream_configs_size() +
2335           stream.audio_send_stream_configs_size() +
2336           stream.video_recv_stream_configs_size() +
2337           stream.video_send_stream_configs_size() +
2338           stream.generic_packets_sent_size() +
2339           stream.generic_packets_received_size() +
2340           stream.generic_acks_received_size(),
2341       1u);
2342 
2343   if (stream.incoming_rtp_packets_size() == 1) {
2344     return StoreIncomingRtpPackets(stream.incoming_rtp_packets(0));
2345   } else if (stream.outgoing_rtp_packets_size() == 1) {
2346     return StoreOutgoingRtpPackets(stream.outgoing_rtp_packets(0));
2347   } else if (stream.incoming_rtcp_packets_size() == 1) {
2348     return StoreIncomingRtcpPackets(stream.incoming_rtcp_packets(0));
2349   } else if (stream.outgoing_rtcp_packets_size() == 1) {
2350     return StoreOutgoingRtcpPackets(stream.outgoing_rtcp_packets(0));
2351   } else if (stream.audio_playout_events_size() == 1) {
2352     return StoreAudioPlayoutEvent(stream.audio_playout_events(0));
2353   } else if (stream.begin_log_events_size() == 1) {
2354     return StoreStartEvent(stream.begin_log_events(0));
2355   } else if (stream.end_log_events_size() == 1) {
2356     return StoreStopEvent(stream.end_log_events(0));
2357   } else if (stream.loss_based_bwe_updates_size() == 1) {
2358     return StoreBweLossBasedUpdate(stream.loss_based_bwe_updates(0));
2359   } else if (stream.delay_based_bwe_updates_size() == 1) {
2360     return StoreBweDelayBasedUpdate(stream.delay_based_bwe_updates(0));
2361   } else if (stream.dtls_transport_state_events_size() == 1) {
2362     return StoreDtlsTransportState(stream.dtls_transport_state_events(0));
2363   } else if (stream.dtls_writable_states_size() == 1) {
2364     return StoreDtlsWritableState(stream.dtls_writable_states(0));
2365   } else if (stream.audio_network_adaptations_size() == 1) {
2366     return StoreAudioNetworkAdaptationEvent(
2367         stream.audio_network_adaptations(0));
2368   } else if (stream.probe_clusters_size() == 1) {
2369     return StoreBweProbeClusterCreated(stream.probe_clusters(0));
2370   } else if (stream.probe_success_size() == 1) {
2371     return StoreBweProbeSuccessEvent(stream.probe_success(0));
2372   } else if (stream.probe_failure_size() == 1) {
2373     return StoreBweProbeFailureEvent(stream.probe_failure(0));
2374   } else if (stream.alr_states_size() == 1) {
2375     return StoreAlrStateEvent(stream.alr_states(0));
2376   } else if (stream.route_changes_size() == 1) {
2377     return StoreRouteChangeEvent(stream.route_changes(0));
2378   } else if (stream.remote_estimates_size() == 1) {
2379     return StoreRemoteEstimateEvent(stream.remote_estimates(0));
2380   } else if (stream.ice_candidate_configs_size() == 1) {
2381     return StoreIceCandidatePairConfig(stream.ice_candidate_configs(0));
2382   } else if (stream.ice_candidate_events_size() == 1) {
2383     return StoreIceCandidateEvent(stream.ice_candidate_events(0));
2384   } else if (stream.audio_recv_stream_configs_size() == 1) {
2385     return StoreAudioRecvConfig(stream.audio_recv_stream_configs(0));
2386   } else if (stream.audio_send_stream_configs_size() == 1) {
2387     return StoreAudioSendConfig(stream.audio_send_stream_configs(0));
2388   } else if (stream.video_recv_stream_configs_size() == 1) {
2389     return StoreVideoRecvConfig(stream.video_recv_stream_configs(0));
2390   } else if (stream.video_send_stream_configs_size() == 1) {
2391     return StoreVideoSendConfig(stream.video_send_stream_configs(0));
2392   } else if (stream.generic_packets_received_size() == 1) {
2393     return StoreGenericPacketReceivedEvent(stream.generic_packets_received(0));
2394   } else if (stream.generic_packets_sent_size() == 1) {
2395     return StoreGenericPacketSentEvent(stream.generic_packets_sent(0));
2396   } else if (stream.generic_acks_received_size() == 1) {
2397     return StoreGenericAckReceivedEvent(stream.generic_acks_received(0));
2398   } else {
2399     RTC_NOTREACHED();
2400     return ParseStatus::Success();
2401   }
2402 }
2403 
StoreAlrStateEvent(const rtclog2::AlrState & proto)2404 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAlrStateEvent(
2405     const rtclog2::AlrState& proto) {
2406   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2407   RTC_PARSE_CHECK_OR_RETURN(proto.has_in_alr());
2408   LoggedAlrStateEvent alr_event;
2409   alr_event.timestamp_us = proto.timestamp_ms() * 1000;
2410   alr_event.in_alr = proto.in_alr();
2411 
2412   alr_state_events_.push_back(alr_event);
2413   // TODO(terelius): Should we delta encode this event type?
2414   return ParseStatus::Success();
2415 }
2416 
StoreRouteChangeEvent(const rtclog2::RouteChange & proto)2417 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreRouteChangeEvent(
2418     const rtclog2::RouteChange& proto) {
2419   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2420   RTC_PARSE_CHECK_OR_RETURN(proto.has_connected());
2421   RTC_PARSE_CHECK_OR_RETURN(proto.has_overhead());
2422   LoggedRouteChangeEvent route_event;
2423   route_event.timestamp_ms = proto.timestamp_ms();
2424   route_event.connected = proto.connected();
2425   route_event.overhead = proto.overhead();
2426 
2427   route_change_events_.push_back(route_event);
2428   // TODO(terelius): Should we delta encode this event type?
2429   return ParseStatus::Success();
2430 }
2431 
StoreRemoteEstimateEvent(const rtclog2::RemoteEstimates & proto)2432 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreRemoteEstimateEvent(
2433     const rtclog2::RemoteEstimates& proto) {
2434   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2435   // Base event
2436   LoggedRemoteEstimateEvent base_event;
2437   base_event.timestamp_ms = proto.timestamp_ms();
2438 
2439   absl::optional<uint64_t> base_link_capacity_lower_kbps;
2440   if (proto.has_link_capacity_lower_kbps()) {
2441     base_link_capacity_lower_kbps = proto.link_capacity_lower_kbps();
2442     base_event.link_capacity_lower =
2443         DataRate::KilobitsPerSec(proto.link_capacity_lower_kbps());
2444   }
2445 
2446   absl::optional<uint64_t> base_link_capacity_upper_kbps;
2447   if (proto.has_link_capacity_upper_kbps()) {
2448     base_link_capacity_upper_kbps = proto.link_capacity_upper_kbps();
2449     base_event.link_capacity_upper =
2450         DataRate::KilobitsPerSec(proto.link_capacity_upper_kbps());
2451   }
2452 
2453   remote_estimate_events_.push_back(base_event);
2454 
2455   const size_t number_of_deltas =
2456       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
2457   if (number_of_deltas == 0) {
2458     return ParseStatus::Success();
2459   }
2460 
2461   // timestamp_ms
2462   auto timestamp_ms_values =
2463       DecodeDeltas(proto.timestamp_ms_deltas(),
2464                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
2465   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
2466 
2467   // link_capacity_lower_kbps
2468   auto link_capacity_lower_kbps_values =
2469       DecodeDeltas(proto.link_capacity_lower_kbps_deltas(),
2470                    base_link_capacity_lower_kbps, number_of_deltas);
2471   RTC_PARSE_CHECK_OR_RETURN_EQ(link_capacity_lower_kbps_values.size(),
2472                                number_of_deltas);
2473 
2474   // link_capacity_upper_kbps
2475   auto link_capacity_upper_kbps_values =
2476       DecodeDeltas(proto.link_capacity_upper_kbps_deltas(),
2477                    base_link_capacity_upper_kbps, number_of_deltas);
2478   RTC_PARSE_CHECK_OR_RETURN_EQ(link_capacity_upper_kbps_values.size(),
2479                                number_of_deltas);
2480 
2481   // Delta decoding
2482   for (size_t i = 0; i < number_of_deltas; ++i) {
2483     LoggedRemoteEstimateEvent event;
2484     RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
2485     event.timestamp_ms = *timestamp_ms_values[i];
2486     if (link_capacity_lower_kbps_values[i])
2487       event.link_capacity_lower =
2488           DataRate::KilobitsPerSec(*link_capacity_lower_kbps_values[i]);
2489     if (link_capacity_upper_kbps_values[i])
2490       event.link_capacity_upper =
2491           DataRate::KilobitsPerSec(*link_capacity_upper_kbps_values[i]);
2492     remote_estimate_events_.push_back(event);
2493   }
2494   return ParseStatus::Success();
2495 }
2496 
StoreAudioPlayoutEvent(const rtclog2::AudioPlayoutEvents & proto)2497 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioPlayoutEvent(
2498     const rtclog2::AudioPlayoutEvents& proto) {
2499   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2500   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
2501 
2502   // Base event
2503   auto map_it = audio_playout_events_[proto.local_ssrc()];
2504   audio_playout_events_[proto.local_ssrc()].emplace_back(
2505       1000 * proto.timestamp_ms(), proto.local_ssrc());
2506 
2507   const size_t number_of_deltas =
2508       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
2509   if (number_of_deltas == 0) {
2510     return ParseStatus::Success();
2511   }
2512 
2513   // timestamp_ms
2514   std::vector<absl::optional<uint64_t>> timestamp_ms_values =
2515       DecodeDeltas(proto.timestamp_ms_deltas(),
2516                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
2517   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
2518 
2519   // local_ssrc
2520   std::vector<absl::optional<uint64_t>> local_ssrc_values = DecodeDeltas(
2521       proto.local_ssrc_deltas(), proto.local_ssrc(), number_of_deltas);
2522   RTC_PARSE_CHECK_OR_RETURN_EQ(local_ssrc_values.size(), number_of_deltas);
2523 
2524   // Delta decoding
2525   for (size_t i = 0; i < number_of_deltas; ++i) {
2526     RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
2527     RTC_PARSE_CHECK_OR_RETURN(local_ssrc_values[i].has_value());
2528     RTC_PARSE_CHECK_OR_RETURN_LE(local_ssrc_values[i].value(),
2529                                  std::numeric_limits<uint32_t>::max());
2530 
2531     int64_t timestamp_ms;
2532     RTC_PARSE_CHECK_OR_RETURN(
2533         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
2534 
2535     const uint32_t local_ssrc =
2536         static_cast<uint32_t>(local_ssrc_values[i].value());
2537     audio_playout_events_[local_ssrc].emplace_back(1000 * timestamp_ms,
2538                                                    local_ssrc);
2539   }
2540   return ParseStatus::Success();
2541 }
2542 
StoreIncomingRtpPackets(const rtclog2::IncomingRtpPackets & proto)2543 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIncomingRtpPackets(
2544     const rtclog2::IncomingRtpPackets& proto) {
2545   return StoreRtpPackets(proto, &incoming_rtp_packets_map_);
2546 }
2547 
StoreOutgoingRtpPackets(const rtclog2::OutgoingRtpPackets & proto)2548 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreOutgoingRtpPackets(
2549     const rtclog2::OutgoingRtpPackets& proto) {
2550   return StoreRtpPackets(proto, &outgoing_rtp_packets_map_);
2551 }
2552 
StoreIncomingRtcpPackets(const rtclog2::IncomingRtcpPackets & proto)2553 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIncomingRtcpPackets(
2554     const rtclog2::IncomingRtcpPackets& proto) {
2555   return StoreRtcpPackets(proto, &incoming_rtcp_packets_,
2556                           /*remove_duplicates=*/true);
2557 }
2558 
StoreOutgoingRtcpPackets(const rtclog2::OutgoingRtcpPackets & proto)2559 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreOutgoingRtcpPackets(
2560     const rtclog2::OutgoingRtcpPackets& proto) {
2561   return StoreRtcpPackets(proto, &outgoing_rtcp_packets_,
2562                           /*remove_duplicates=*/false);
2563 }
2564 
StoreStartEvent(const rtclog2::BeginLogEvent & proto)2565 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreStartEvent(
2566     const rtclog2::BeginLogEvent& proto) {
2567   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2568   RTC_PARSE_CHECK_OR_RETURN(proto.has_version());
2569   RTC_PARSE_CHECK_OR_RETURN(proto.has_utc_time_ms());
2570   RTC_PARSE_CHECK_OR_RETURN_EQ(proto.version(), 2);
2571   LoggedStartEvent start_event(proto.timestamp_ms() * 1000,
2572                                proto.utc_time_ms());
2573 
2574   start_log_events_.push_back(start_event);
2575   return ParseStatus::Success();
2576 }
2577 
StoreStopEvent(const rtclog2::EndLogEvent & proto)2578 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreStopEvent(
2579     const rtclog2::EndLogEvent& proto) {
2580   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2581   LoggedStopEvent stop_event(proto.timestamp_ms() * 1000);
2582 
2583   stop_log_events_.push_back(stop_event);
2584   return ParseStatus::Success();
2585 }
2586 
StoreBweLossBasedUpdate(const rtclog2::LossBasedBweUpdates & proto)2587 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweLossBasedUpdate(
2588     const rtclog2::LossBasedBweUpdates& proto) {
2589   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2590   RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
2591   RTC_PARSE_CHECK_OR_RETURN(proto.has_fraction_loss());
2592   RTC_PARSE_CHECK_OR_RETURN(proto.has_total_packets());
2593 
2594   // Base event
2595   bwe_loss_updates_.emplace_back(1000 * proto.timestamp_ms(),
2596                                  proto.bitrate_bps(), proto.fraction_loss(),
2597                                  proto.total_packets());
2598 
2599   const size_t number_of_deltas =
2600       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
2601   if (number_of_deltas == 0) {
2602     return ParseStatus::Success();
2603   }
2604 
2605   // timestamp_ms
2606   std::vector<absl::optional<uint64_t>> timestamp_ms_values =
2607       DecodeDeltas(proto.timestamp_ms_deltas(),
2608                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
2609   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
2610 
2611   // bitrate_bps
2612   std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
2613       proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
2614   RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
2615 
2616   // fraction_loss
2617   std::vector<absl::optional<uint64_t>> fraction_loss_values = DecodeDeltas(
2618       proto.fraction_loss_deltas(), proto.fraction_loss(), number_of_deltas);
2619   RTC_PARSE_CHECK_OR_RETURN_EQ(fraction_loss_values.size(), number_of_deltas);
2620 
2621   // total_packets
2622   std::vector<absl::optional<uint64_t>> total_packets_values = DecodeDeltas(
2623       proto.total_packets_deltas(), proto.total_packets(), number_of_deltas);
2624   RTC_PARSE_CHECK_OR_RETURN_EQ(total_packets_values.size(), number_of_deltas);
2625 
2626   // Delta decoding
2627   for (size_t i = 0; i < number_of_deltas; ++i) {
2628     RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
2629     int64_t timestamp_ms;
2630     RTC_PARSE_CHECK_OR_RETURN(
2631         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
2632 
2633     RTC_PARSE_CHECK_OR_RETURN(bitrate_bps_values[i].has_value());
2634     RTC_PARSE_CHECK_OR_RETURN_LE(bitrate_bps_values[i].value(),
2635                                  std::numeric_limits<uint32_t>::max());
2636     const uint32_t bitrate_bps =
2637         static_cast<uint32_t>(bitrate_bps_values[i].value());
2638 
2639     RTC_PARSE_CHECK_OR_RETURN(fraction_loss_values[i].has_value());
2640     RTC_PARSE_CHECK_OR_RETURN_LE(fraction_loss_values[i].value(),
2641                                  std::numeric_limits<uint32_t>::max());
2642     const uint32_t fraction_loss =
2643         static_cast<uint32_t>(fraction_loss_values[i].value());
2644 
2645     RTC_PARSE_CHECK_OR_RETURN(total_packets_values[i].has_value());
2646     RTC_PARSE_CHECK_OR_RETURN_LE(total_packets_values[i].value(),
2647                                  std::numeric_limits<uint32_t>::max());
2648     const uint32_t total_packets =
2649         static_cast<uint32_t>(total_packets_values[i].value());
2650 
2651     bwe_loss_updates_.emplace_back(1000 * timestamp_ms, bitrate_bps,
2652                                    fraction_loss, total_packets);
2653   }
2654   return ParseStatus::Success();
2655 }
2656 
StoreBweDelayBasedUpdate(const rtclog2::DelayBasedBweUpdates & proto)2657 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweDelayBasedUpdate(
2658     const rtclog2::DelayBasedBweUpdates& proto) {
2659   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2660   RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
2661   RTC_PARSE_CHECK_OR_RETURN(proto.has_detector_state());
2662 
2663   // Base event
2664   const BandwidthUsage base_detector_state =
2665       GetRuntimeDetectorState(proto.detector_state());
2666   bwe_delay_updates_.emplace_back(1000 * proto.timestamp_ms(),
2667                                   proto.bitrate_bps(), base_detector_state);
2668 
2669   const size_t number_of_deltas =
2670       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
2671   if (number_of_deltas == 0) {
2672     return ParseStatus::Success();
2673   }
2674 
2675   // timestamp_ms
2676   std::vector<absl::optional<uint64_t>> timestamp_ms_values =
2677       DecodeDeltas(proto.timestamp_ms_deltas(),
2678                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
2679   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
2680 
2681   // bitrate_bps
2682   std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
2683       proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
2684   RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
2685 
2686   // detector_state
2687   std::vector<absl::optional<uint64_t>> detector_state_values = DecodeDeltas(
2688       proto.detector_state_deltas(),
2689       static_cast<uint64_t>(proto.detector_state()), number_of_deltas);
2690   RTC_PARSE_CHECK_OR_RETURN_EQ(detector_state_values.size(), number_of_deltas);
2691 
2692   // Delta decoding
2693   for (size_t i = 0; i < number_of_deltas; ++i) {
2694     RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
2695     int64_t timestamp_ms;
2696     RTC_PARSE_CHECK_OR_RETURN(
2697         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
2698 
2699     RTC_PARSE_CHECK_OR_RETURN(bitrate_bps_values[i].has_value());
2700     RTC_PARSE_CHECK_OR_RETURN_LE(bitrate_bps_values[i].value(),
2701                                  std::numeric_limits<uint32_t>::max());
2702     const uint32_t bitrate_bps =
2703         static_cast<uint32_t>(bitrate_bps_values[i].value());
2704 
2705     RTC_PARSE_CHECK_OR_RETURN(detector_state_values[i].has_value());
2706     const auto detector_state =
2707         static_cast<rtclog2::DelayBasedBweUpdates::DetectorState>(
2708             detector_state_values[i].value());
2709 
2710     bwe_delay_updates_.emplace_back(1000 * timestamp_ms, bitrate_bps,
2711                                     GetRuntimeDetectorState(detector_state));
2712   }
2713   return ParseStatus::Success();
2714 }
2715 
StoreBweProbeClusterCreated(const rtclog2::BweProbeCluster & proto)2716 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeClusterCreated(
2717     const rtclog2::BweProbeCluster& proto) {
2718   LoggedBweProbeClusterCreatedEvent probe_cluster;
2719   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2720   probe_cluster.timestamp_us = proto.timestamp_ms() * 1000;
2721   RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
2722   probe_cluster.id = proto.id();
2723   RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
2724   probe_cluster.bitrate_bps = proto.bitrate_bps();
2725   RTC_PARSE_CHECK_OR_RETURN(proto.has_min_packets());
2726   probe_cluster.min_packets = proto.min_packets();
2727   RTC_PARSE_CHECK_OR_RETURN(proto.has_min_bytes());
2728   probe_cluster.min_bytes = proto.min_bytes();
2729 
2730   bwe_probe_cluster_created_events_.push_back(probe_cluster);
2731 
2732   // TODO(terelius): Should we delta encode this event type?
2733   return ParseStatus::Success();
2734 }
2735 
StoreBweProbeSuccessEvent(const rtclog2::BweProbeResultSuccess & proto)2736 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeSuccessEvent(
2737     const rtclog2::BweProbeResultSuccess& proto) {
2738   LoggedBweProbeSuccessEvent probe_result;
2739   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2740   probe_result.timestamp_us = proto.timestamp_ms() * 1000;
2741   RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
2742   probe_result.id = proto.id();
2743   RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
2744   probe_result.bitrate_bps = proto.bitrate_bps();
2745 
2746   bwe_probe_success_events_.push_back(probe_result);
2747 
2748   // TODO(terelius): Should we delta encode this event type?
2749   return ParseStatus::Success();
2750 }
2751 
StoreBweProbeFailureEvent(const rtclog2::BweProbeResultFailure & proto)2752 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreBweProbeFailureEvent(
2753     const rtclog2::BweProbeResultFailure& proto) {
2754   LoggedBweProbeFailureEvent probe_result;
2755   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2756   probe_result.timestamp_us = proto.timestamp_ms() * 1000;
2757   RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
2758   probe_result.id = proto.id();
2759   RTC_PARSE_CHECK_OR_RETURN(proto.has_failure());
2760   probe_result.failure_reason = GetRuntimeProbeFailureReason(proto.failure());
2761 
2762   bwe_probe_failure_events_.push_back(probe_result);
2763 
2764   // TODO(terelius): Should we delta encode this event type?
2765   return ParseStatus::Success();
2766 }
2767 
StoreGenericAckReceivedEvent(const rtclog2::GenericAckReceived & proto)2768 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreGenericAckReceivedEvent(
2769     const rtclog2::GenericAckReceived& proto) {
2770   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2771   RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
2772   RTC_PARSE_CHECK_OR_RETURN(proto.has_acked_packet_number());
2773   // receive_acked_packet_time_ms is optional.
2774 
2775   absl::optional<int64_t> base_receive_acked_packet_time_ms;
2776   if (proto.has_receive_acked_packet_time_ms()) {
2777     base_receive_acked_packet_time_ms = proto.receive_acked_packet_time_ms();
2778   }
2779   generic_acks_received_.push_back(
2780       {proto.timestamp_ms() * 1000, proto.packet_number(),
2781        proto.acked_packet_number(), base_receive_acked_packet_time_ms});
2782 
2783   const size_t number_of_deltas =
2784       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
2785   if (number_of_deltas == 0) {
2786     return ParseStatus::Success();
2787   }
2788 
2789   // timestamp_ms
2790   std::vector<absl::optional<uint64_t>> timestamp_ms_values =
2791       DecodeDeltas(proto.timestamp_ms_deltas(),
2792                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
2793   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
2794 
2795   // packet_number
2796   std::vector<absl::optional<uint64_t>> packet_number_values =
2797       DecodeDeltas(proto.packet_number_deltas(),
2798                    ToUnsigned(proto.packet_number()), number_of_deltas);
2799   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
2800 
2801   // acked_packet_number
2802   std::vector<absl::optional<uint64_t>> acked_packet_number_values =
2803       DecodeDeltas(proto.acked_packet_number_deltas(),
2804                    ToUnsigned(proto.acked_packet_number()), number_of_deltas);
2805   RTC_PARSE_CHECK_OR_RETURN_EQ(acked_packet_number_values.size(),
2806                                number_of_deltas);
2807 
2808   // optional receive_acked_packet_time_ms
2809   const absl::optional<uint64_t> unsigned_receive_acked_packet_time_ms_base =
2810       proto.has_receive_acked_packet_time_ms()
2811           ? absl::optional<uint64_t>(
2812                 ToUnsigned(proto.receive_acked_packet_time_ms()))
2813           : absl::optional<uint64_t>();
2814   std::vector<absl::optional<uint64_t>> receive_acked_packet_time_ms_values =
2815       DecodeDeltas(proto.receive_acked_packet_time_ms_deltas(),
2816                    unsigned_receive_acked_packet_time_ms_base,
2817                    number_of_deltas);
2818   RTC_PARSE_CHECK_OR_RETURN_EQ(receive_acked_packet_time_ms_values.size(),
2819                                number_of_deltas);
2820 
2821   for (size_t i = 0; i < number_of_deltas; i++) {
2822     int64_t timestamp_ms;
2823     RTC_PARSE_CHECK_OR_RETURN(
2824         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
2825     int64_t packet_number;
2826     RTC_PARSE_CHECK_OR_RETURN(
2827         ToSigned(packet_number_values[i].value(), &packet_number));
2828     int64_t acked_packet_number;
2829     RTC_PARSE_CHECK_OR_RETURN(
2830         ToSigned(acked_packet_number_values[i].value(), &acked_packet_number));
2831     absl::optional<int64_t> receive_acked_packet_time_ms;
2832 
2833     if (receive_acked_packet_time_ms_values[i].has_value()) {
2834       int64_t value;
2835       RTC_PARSE_CHECK_OR_RETURN(
2836           ToSigned(receive_acked_packet_time_ms_values[i].value(), &value));
2837       receive_acked_packet_time_ms = value;
2838     }
2839     generic_acks_received_.push_back({timestamp_ms * 1000, packet_number,
2840                                       acked_packet_number,
2841                                       receive_acked_packet_time_ms});
2842   }
2843   return ParseStatus::Success();
2844 }
2845 
StoreGenericPacketSentEvent(const rtclog2::GenericPacketSent & proto)2846 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreGenericPacketSentEvent(
2847     const rtclog2::GenericPacketSent& proto) {
2848   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2849 
2850   // Base event
2851   RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
2852   RTC_PARSE_CHECK_OR_RETURN(proto.has_overhead_length());
2853   RTC_PARSE_CHECK_OR_RETURN(proto.has_payload_length());
2854   RTC_PARSE_CHECK_OR_RETURN(proto.has_padding_length());
2855 
2856   generic_packets_sent_.push_back(
2857       {proto.timestamp_ms() * 1000, proto.packet_number(),
2858        static_cast<size_t>(proto.overhead_length()),
2859        static_cast<size_t>(proto.payload_length()),
2860        static_cast<size_t>(proto.padding_length())});
2861 
2862   const size_t number_of_deltas =
2863       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
2864   if (number_of_deltas == 0) {
2865     return ParseStatus::Success();
2866   }
2867 
2868   // timestamp_ms
2869   std::vector<absl::optional<uint64_t>> timestamp_ms_values =
2870       DecodeDeltas(proto.timestamp_ms_deltas(),
2871                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
2872   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
2873 
2874   // packet_number
2875   std::vector<absl::optional<uint64_t>> packet_number_values =
2876       DecodeDeltas(proto.packet_number_deltas(),
2877                    ToUnsigned(proto.packet_number()), number_of_deltas);
2878   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
2879 
2880   std::vector<absl::optional<uint64_t>> overhead_length_values =
2881       DecodeDeltas(proto.overhead_length_deltas(), proto.overhead_length(),
2882                    number_of_deltas);
2883   RTC_PARSE_CHECK_OR_RETURN_EQ(overhead_length_values.size(), number_of_deltas);
2884 
2885   std::vector<absl::optional<uint64_t>> payload_length_values =
2886       DecodeDeltas(proto.payload_length_deltas(),
2887                    ToUnsigned(proto.payload_length()), number_of_deltas);
2888   RTC_PARSE_CHECK_OR_RETURN_EQ(payload_length_values.size(), number_of_deltas);
2889 
2890   std::vector<absl::optional<uint64_t>> padding_length_values =
2891       DecodeDeltas(proto.padding_length_deltas(),
2892                    ToUnsigned(proto.padding_length()), number_of_deltas);
2893   RTC_PARSE_CHECK_OR_RETURN_EQ(padding_length_values.size(), number_of_deltas);
2894 
2895   for (size_t i = 0; i < number_of_deltas; i++) {
2896     int64_t timestamp_ms;
2897     RTC_PARSE_CHECK_OR_RETURN(
2898         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
2899     int64_t packet_number;
2900     RTC_PARSE_CHECK_OR_RETURN(
2901         ToSigned(packet_number_values[i].value(), &packet_number));
2902     RTC_PARSE_CHECK_OR_RETURN(overhead_length_values[i].has_value());
2903     RTC_PARSE_CHECK_OR_RETURN(payload_length_values[i].has_value());
2904     RTC_PARSE_CHECK_OR_RETURN(padding_length_values[i].has_value());
2905     generic_packets_sent_.push_back(
2906         {timestamp_ms * 1000, packet_number,
2907          static_cast<size_t>(overhead_length_values[i].value()),
2908          static_cast<size_t>(payload_length_values[i].value()),
2909          static_cast<size_t>(padding_length_values[i].value())});
2910   }
2911   return ParseStatus::Success();
2912 }
2913 
2914 ParsedRtcEventLog::ParseStatus
StoreGenericPacketReceivedEvent(const rtclog2::GenericPacketReceived & proto)2915 ParsedRtcEventLog::StoreGenericPacketReceivedEvent(
2916     const rtclog2::GenericPacketReceived& proto) {
2917   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2918 
2919   // Base event
2920   RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
2921   RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_length());
2922 
2923   generic_packets_received_.push_back({proto.timestamp_ms() * 1000,
2924                                        proto.packet_number(),
2925                                        proto.packet_length()});
2926 
2927   const size_t number_of_deltas =
2928       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
2929   if (number_of_deltas == 0) {
2930     return ParseStatus::Success();
2931   }
2932 
2933   // timestamp_ms
2934   std::vector<absl::optional<uint64_t>> timestamp_ms_values =
2935       DecodeDeltas(proto.timestamp_ms_deltas(),
2936                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
2937   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
2938 
2939   // packet_number
2940   std::vector<absl::optional<uint64_t>> packet_number_values =
2941       DecodeDeltas(proto.packet_number_deltas(),
2942                    ToUnsigned(proto.packet_number()), number_of_deltas);
2943   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
2944 
2945   std::vector<absl::optional<uint64_t>> packet_length_values = DecodeDeltas(
2946       proto.packet_length_deltas(), proto.packet_length(), number_of_deltas);
2947   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_length_values.size(), number_of_deltas);
2948 
2949   for (size_t i = 0; i < number_of_deltas; i++) {
2950     int64_t timestamp_ms;
2951     RTC_PARSE_CHECK_OR_RETURN(
2952         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
2953     int64_t packet_number;
2954     RTC_PARSE_CHECK_OR_RETURN(
2955         ToSigned(packet_number_values[i].value(), &packet_number));
2956     int32_t packet_length;
2957     RTC_PARSE_CHECK_OR_RETURN(
2958         ToSigned(packet_length_values[i].value(), &packet_length));
2959     generic_packets_received_.push_back(
2960         {timestamp_ms * 1000, packet_number, packet_length});
2961   }
2962   return ParseStatus::Success();
2963 }
2964 
2965 ParsedRtcEventLog::ParseStatus
StoreAudioNetworkAdaptationEvent(const rtclog2::AudioNetworkAdaptations & proto)2966 ParsedRtcEventLog::StoreAudioNetworkAdaptationEvent(
2967     const rtclog2::AudioNetworkAdaptations& proto) {
2968   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
2969 
2970   // Base event
2971   {
2972     AudioEncoderRuntimeConfig runtime_config;
2973     if (proto.has_bitrate_bps()) {
2974       runtime_config.bitrate_bps = proto.bitrate_bps();
2975     }
2976     if (proto.has_frame_length_ms()) {
2977       runtime_config.frame_length_ms = proto.frame_length_ms();
2978     }
2979     if (proto.has_uplink_packet_loss_fraction()) {
2980       float uplink_packet_loss_fraction;
2981       RTC_PARSE_CHECK_OR_RETURN(ParsePacketLossFractionFromProtoFormat(
2982           proto.uplink_packet_loss_fraction(), &uplink_packet_loss_fraction));
2983       runtime_config.uplink_packet_loss_fraction = uplink_packet_loss_fraction;
2984     }
2985     if (proto.has_enable_fec()) {
2986       runtime_config.enable_fec = proto.enable_fec();
2987     }
2988     if (proto.has_enable_dtx()) {
2989       runtime_config.enable_dtx = proto.enable_dtx();
2990     }
2991     if (proto.has_num_channels()) {
2992       // Note: Encoding N as N-1 only done for |num_channels_deltas|.
2993       runtime_config.num_channels = proto.num_channels();
2994     }
2995     audio_network_adaptation_events_.emplace_back(1000 * proto.timestamp_ms(),
2996                                                   runtime_config);
2997   }
2998 
2999   const size_t number_of_deltas =
3000       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
3001   if (number_of_deltas == 0) {
3002     return ParseStatus::Success();
3003   }
3004 
3005   // timestamp_ms
3006   std::vector<absl::optional<uint64_t>> timestamp_ms_values =
3007       DecodeDeltas(proto.timestamp_ms_deltas(),
3008                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
3009   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
3010 
3011   // bitrate_bps
3012   const absl::optional<uint64_t> unsigned_base_bitrate_bps =
3013       proto.has_bitrate_bps()
3014           ? absl::optional<uint64_t>(ToUnsigned(proto.bitrate_bps()))
3015           : absl::optional<uint64_t>();
3016   std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
3017       proto.bitrate_bps_deltas(), unsigned_base_bitrate_bps, number_of_deltas);
3018   RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
3019 
3020   // frame_length_ms
3021   const absl::optional<uint64_t> unsigned_base_frame_length_ms =
3022       proto.has_frame_length_ms()
3023           ? absl::optional<uint64_t>(ToUnsigned(proto.frame_length_ms()))
3024           : absl::optional<uint64_t>();
3025   std::vector<absl::optional<uint64_t>> frame_length_ms_values =
3026       DecodeDeltas(proto.frame_length_ms_deltas(),
3027                    unsigned_base_frame_length_ms, number_of_deltas);
3028   RTC_PARSE_CHECK_OR_RETURN_EQ(frame_length_ms_values.size(), number_of_deltas);
3029 
3030   // uplink_packet_loss_fraction
3031   const absl::optional<uint64_t> uplink_packet_loss_fraction =
3032       proto.has_uplink_packet_loss_fraction()
3033           ? absl::optional<uint64_t>(proto.uplink_packet_loss_fraction())
3034           : absl::optional<uint64_t>();
3035   std::vector<absl::optional<uint64_t>> uplink_packet_loss_fraction_values =
3036       DecodeDeltas(proto.uplink_packet_loss_fraction_deltas(),
3037                    uplink_packet_loss_fraction, number_of_deltas);
3038   RTC_PARSE_CHECK_OR_RETURN_EQ(uplink_packet_loss_fraction_values.size(),
3039                                number_of_deltas);
3040 
3041   // enable_fec
3042   const absl::optional<uint64_t> enable_fec =
3043       proto.has_enable_fec() ? absl::optional<uint64_t>(proto.enable_fec())
3044                              : absl::optional<uint64_t>();
3045   std::vector<absl::optional<uint64_t>> enable_fec_values =
3046       DecodeDeltas(proto.enable_fec_deltas(), enable_fec, number_of_deltas);
3047   RTC_PARSE_CHECK_OR_RETURN_EQ(enable_fec_values.size(), number_of_deltas);
3048 
3049   // enable_dtx
3050   const absl::optional<uint64_t> enable_dtx =
3051       proto.has_enable_dtx() ? absl::optional<uint64_t>(proto.enable_dtx())
3052                              : absl::optional<uint64_t>();
3053   std::vector<absl::optional<uint64_t>> enable_dtx_values =
3054       DecodeDeltas(proto.enable_dtx_deltas(), enable_dtx, number_of_deltas);
3055   RTC_PARSE_CHECK_OR_RETURN_EQ(enable_dtx_values.size(), number_of_deltas);
3056 
3057   // num_channels
3058   // Note: For delta encoding, all num_channel values, including the base,
3059   // were shifted down by one, but in the base event, they were not.
3060   // We likewise shift the base event down by one, to get the same base as
3061   // encoding had, but then shift all of the values (except the base) back up
3062   // to their original value.
3063   absl::optional<uint64_t> shifted_base_num_channels;
3064   if (proto.has_num_channels()) {
3065     shifted_base_num_channels =
3066         absl::optional<uint64_t>(proto.num_channels() - 1);
3067   }
3068   std::vector<absl::optional<uint64_t>> num_channels_values = DecodeDeltas(
3069       proto.num_channels_deltas(), shifted_base_num_channels, number_of_deltas);
3070   for (size_t i = 0; i < num_channels_values.size(); ++i) {
3071     if (num_channels_values[i].has_value()) {
3072       num_channels_values[i] = num_channels_values[i].value() + 1;
3073     }
3074   }
3075   RTC_PARSE_CHECK_OR_RETURN_EQ(num_channels_values.size(), number_of_deltas);
3076 
3077   // Delta decoding
3078   for (size_t i = 0; i < number_of_deltas; ++i) {
3079     RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
3080     int64_t timestamp_ms;
3081     RTC_PARSE_CHECK_OR_RETURN(
3082         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
3083 
3084     AudioEncoderRuntimeConfig runtime_config;
3085     if (bitrate_bps_values[i].has_value()) {
3086       int signed_bitrate_bps;
3087       RTC_PARSE_CHECK_OR_RETURN(
3088           ToSigned(bitrate_bps_values[i].value(), &signed_bitrate_bps));
3089       runtime_config.bitrate_bps = signed_bitrate_bps;
3090     }
3091     if (frame_length_ms_values[i].has_value()) {
3092       int signed_frame_length_ms;
3093       RTC_PARSE_CHECK_OR_RETURN(
3094           ToSigned(frame_length_ms_values[i].value(), &signed_frame_length_ms));
3095       runtime_config.frame_length_ms = signed_frame_length_ms;
3096     }
3097     if (uplink_packet_loss_fraction_values[i].has_value()) {
3098       float uplink_packet_loss_fraction;
3099       RTC_PARSE_CHECK_OR_RETURN(ParsePacketLossFractionFromProtoFormat(
3100           rtc::checked_cast<uint32_t>(
3101               uplink_packet_loss_fraction_values[i].value()),
3102           &uplink_packet_loss_fraction));
3103       runtime_config.uplink_packet_loss_fraction = uplink_packet_loss_fraction;
3104     }
3105     if (enable_fec_values[i].has_value()) {
3106       runtime_config.enable_fec =
3107           rtc::checked_cast<bool>(enable_fec_values[i].value());
3108     }
3109     if (enable_dtx_values[i].has_value()) {
3110       runtime_config.enable_dtx =
3111           rtc::checked_cast<bool>(enable_dtx_values[i].value());
3112     }
3113     if (num_channels_values[i].has_value()) {
3114       runtime_config.num_channels =
3115           rtc::checked_cast<size_t>(num_channels_values[i].value());
3116     }
3117     audio_network_adaptation_events_.emplace_back(1000 * timestamp_ms,
3118                                                   runtime_config);
3119   }
3120   return ParseStatus::Success();
3121 }
3122 
StoreDtlsTransportState(const rtclog2::DtlsTransportStateEvent & proto)3123 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreDtlsTransportState(
3124     const rtclog2::DtlsTransportStateEvent& proto) {
3125   LoggedDtlsTransportState dtls_state;
3126   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3127   dtls_state.timestamp_us = proto.timestamp_ms() * 1000;
3128 
3129   RTC_PARSE_CHECK_OR_RETURN(proto.has_dtls_transport_state());
3130   dtls_state.dtls_transport_state =
3131       GetRuntimeDtlsTransportState(proto.dtls_transport_state());
3132 
3133   dtls_transport_states_.push_back(dtls_state);
3134   return ParseStatus::Success();
3135 }
3136 
StoreDtlsWritableState(const rtclog2::DtlsWritableState & proto)3137 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreDtlsWritableState(
3138     const rtclog2::DtlsWritableState& proto) {
3139   LoggedDtlsWritableState dtls_writable_state;
3140   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3141   dtls_writable_state.timestamp_us = proto.timestamp_ms() * 1000;
3142   RTC_PARSE_CHECK_OR_RETURN(proto.has_writable());
3143   dtls_writable_state.writable = proto.writable();
3144 
3145   dtls_writable_states_.push_back(dtls_writable_state);
3146   return ParseStatus::Success();
3147 }
3148 
StoreIceCandidatePairConfig(const rtclog2::IceCandidatePairConfig & proto)3149 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidatePairConfig(
3150     const rtclog2::IceCandidatePairConfig& proto) {
3151   LoggedIceCandidatePairConfig ice_config;
3152   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3153   ice_config.timestamp_us = proto.timestamp_ms() * 1000;
3154 
3155   RTC_PARSE_CHECK_OR_RETURN(proto.has_config_type());
3156   ice_config.type = GetRuntimeIceCandidatePairConfigType(proto.config_type());
3157   RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id());
3158   ice_config.candidate_pair_id = proto.candidate_pair_id();
3159   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_candidate_type());
3160   ice_config.local_candidate_type =
3161       GetRuntimeIceCandidateType(proto.local_candidate_type());
3162   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_relay_protocol());
3163   ice_config.local_relay_protocol =
3164       GetRuntimeIceCandidatePairProtocol(proto.local_relay_protocol());
3165   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_network_type());
3166   ice_config.local_network_type =
3167       GetRuntimeIceCandidateNetworkType(proto.local_network_type());
3168   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_address_family());
3169   ice_config.local_address_family =
3170       GetRuntimeIceCandidatePairAddressFamily(proto.local_address_family());
3171   RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_candidate_type());
3172   ice_config.remote_candidate_type =
3173       GetRuntimeIceCandidateType(proto.remote_candidate_type());
3174   RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_address_family());
3175   ice_config.remote_address_family =
3176       GetRuntimeIceCandidatePairAddressFamily(proto.remote_address_family());
3177   RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_protocol());
3178   ice_config.candidate_pair_protocol =
3179       GetRuntimeIceCandidatePairProtocol(proto.candidate_pair_protocol());
3180 
3181   ice_candidate_pair_configs_.push_back(ice_config);
3182 
3183   // TODO(terelius): Should we delta encode this event type?
3184   return ParseStatus::Success();
3185 }
3186 
StoreIceCandidateEvent(const rtclog2::IceCandidatePairEvent & proto)3187 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidateEvent(
3188     const rtclog2::IceCandidatePairEvent& proto) {
3189   LoggedIceCandidatePairEvent ice_event;
3190   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3191   ice_event.timestamp_us = proto.timestamp_ms() * 1000;
3192   RTC_PARSE_CHECK_OR_RETURN(proto.has_event_type());
3193   ice_event.type = GetRuntimeIceCandidatePairEventType(proto.event_type());
3194   RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id());
3195   ice_event.candidate_pair_id = proto.candidate_pair_id();
3196   // TODO(zstein): Make the transaction_id field required once all old versions
3197   // of the log (which don't have the field) are obsolete.
3198   ice_event.transaction_id =
3199       proto.has_transaction_id() ? proto.transaction_id() : 0;
3200 
3201   ice_candidate_pair_events_.push_back(ice_event);
3202 
3203   // TODO(terelius): Should we delta encode this event type?
3204   return ParseStatus::Success();
3205 }
3206 
StoreVideoRecvConfig(const rtclog2::VideoRecvStreamConfig & proto)3207 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreVideoRecvConfig(
3208     const rtclog2::VideoRecvStreamConfig& proto) {
3209   LoggedVideoRecvConfig stream;
3210   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3211   stream.timestamp_us = proto.timestamp_ms() * 1000;
3212   RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
3213   stream.config.remote_ssrc = proto.remote_ssrc();
3214   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
3215   stream.config.local_ssrc = proto.local_ssrc();
3216   if (proto.has_rtx_ssrc()) {
3217     stream.config.rtx_ssrc = proto.rtx_ssrc();
3218   }
3219   if (proto.has_header_extensions()) {
3220     stream.config.rtp_extensions =
3221         GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
3222   }
3223   video_recv_configs_.push_back(stream);
3224   return ParseStatus::Success();
3225 }
3226 
StoreVideoSendConfig(const rtclog2::VideoSendStreamConfig & proto)3227 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreVideoSendConfig(
3228     const rtclog2::VideoSendStreamConfig& proto) {
3229   LoggedVideoSendConfig stream;
3230   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3231   stream.timestamp_us = proto.timestamp_ms() * 1000;
3232   RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
3233   stream.config.local_ssrc = proto.ssrc();
3234   if (proto.has_rtx_ssrc()) {
3235     stream.config.rtx_ssrc = proto.rtx_ssrc();
3236   }
3237   if (proto.has_header_extensions()) {
3238     stream.config.rtp_extensions =
3239         GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
3240   }
3241   video_send_configs_.push_back(stream);
3242   return ParseStatus::Success();
3243 }
3244 
StoreAudioRecvConfig(const rtclog2::AudioRecvStreamConfig & proto)3245 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioRecvConfig(
3246     const rtclog2::AudioRecvStreamConfig& proto) {
3247   LoggedAudioRecvConfig stream;
3248   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3249   stream.timestamp_us = proto.timestamp_ms() * 1000;
3250   RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
3251   stream.config.remote_ssrc = proto.remote_ssrc();
3252   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
3253   stream.config.local_ssrc = proto.local_ssrc();
3254   if (proto.has_header_extensions()) {
3255     stream.config.rtp_extensions =
3256         GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
3257   }
3258   audio_recv_configs_.push_back(stream);
3259   return ParseStatus::Success();
3260 }
3261 
StoreAudioSendConfig(const rtclog2::AudioSendStreamConfig & proto)3262 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioSendConfig(
3263     const rtclog2::AudioSendStreamConfig& proto) {
3264   LoggedAudioSendConfig stream;
3265   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
3266   stream.timestamp_us = proto.timestamp_ms() * 1000;
3267   RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
3268   stream.config.local_ssrc = proto.ssrc();
3269   if (proto.has_header_extensions()) {
3270     stream.config.rtp_extensions =
3271         GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
3272   }
3273   audio_send_configs_.push_back(stream);
3274   return ParseStatus::Success();
3275 }
3276 
3277 }  // namespace webrtc
3278