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