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