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