xref: /aosp_15_r20/external/webrtc/rtc_tools/rtc_event_log_to_text/converter.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2022 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 "rtc_tools/rtc_event_log_to_text/converter.h"
12 
13 #include <inttypes.h>
14 
15 #include <map>
16 #include <vector>
17 
18 #include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
19 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
20 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
21 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
22 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
23 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
24 #include "logging/rtc_event_log/events/rtc_event_begin_log.h"
25 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
26 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
27 #include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
28 #include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
29 #include "logging/rtc_event_log/events/rtc_event_end_log.h"
30 #include "logging/rtc_event_log/events/rtc_event_frame_decoded.h"
31 #include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
32 #include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
33 #include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
34 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
35 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
36 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
37 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
38 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
39 #include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
40 #include "logging/rtc_event_log/events/rtc_event_route_change.h"
41 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
42 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
43 #include "logging/rtc_event_log/rtc_event_log_parser.h"
44 #include "logging/rtc_event_log/rtc_event_processor.h"
45 #include "logging/rtc_event_log/rtc_stream_config.h"
46 #include "rtc_base/logging.h"
47 
48 namespace webrtc {
49 namespace {
50 
PrintHeaderExtensionConfig(FILE * output,const std::vector<RtpExtension> & rtp_extensions)51 void PrintHeaderExtensionConfig(
52     FILE* output,
53     const std::vector<RtpExtension>& rtp_extensions) {
54   if (rtp_extensions.empty())
55     return;
56   fprintf(output, " extension_map=");
57   for (const RtpExtension& extension : rtp_extensions) {
58     fprintf(output, "{uri:%s,id:%d}", extension.uri.c_str(), extension.id);
59   }
60 }
61 
62 }  // namespace
63 
Convert(std::string inputfile,FILE * output,ParsedRtcEventLog::UnconfiguredHeaderExtensions handle_unconfigured_extensions)64 bool Convert(std::string inputfile,
65              FILE* output,
66              ParsedRtcEventLog::UnconfiguredHeaderExtensions
67                  handle_unconfigured_extensions) {
68   ParsedRtcEventLog parsed_log(handle_unconfigured_extensions,
69                                /*allow_incomplete_logs=*/true);
70 
71   auto status = parsed_log.ParseFile(inputfile);
72   if (!status.ok()) {
73     RTC_LOG(LS_ERROR) << "Failed to parse " << inputfile << ": "
74                       << status.message();
75     return false;
76   }
77 
78   auto audio_recv_stream_handler = [&](const LoggedAudioRecvConfig& event) {
79     fprintf(output, "AUDIO_RECV_STREAM_CONFIG %" PRId64, event.log_time_ms());
80     fprintf(output, " remote_ssrc=%u", event.config.remote_ssrc);
81     fprintf(output, " local_ssrc=%u", event.config.local_ssrc);
82     PrintHeaderExtensionConfig(output, event.config.rtp_extensions);
83     fprintf(output, "\n");
84   };
85 
86   auto audio_send_stream_handler = [&](const LoggedAudioSendConfig& event) {
87     fprintf(output, "AUDIO_SEND_STREAM_CONFIG %" PRId64, event.log_time_ms());
88     fprintf(output, " ssrc=%u", event.config.local_ssrc);
89     PrintHeaderExtensionConfig(output, event.config.rtp_extensions);
90     fprintf(output, "\n");
91   };
92 
93   auto video_recv_stream_handler = [&](const LoggedVideoRecvConfig& event) {
94     fprintf(output, "VIDEO_RECV_STREAM_CONFIG %" PRId64, event.log_time_ms());
95     fprintf(output, " remote_ssrc=%u", event.config.remote_ssrc);
96     fprintf(output, " local_ssrc=%u", event.config.local_ssrc);
97     fprintf(output, " rtx_ssrc=%u", event.config.rtx_ssrc);
98     PrintHeaderExtensionConfig(output, event.config.rtp_extensions);
99     fprintf(output, "\n");
100   };
101 
102   auto video_send_stream_handler = [&](const LoggedVideoSendConfig& event) {
103     fprintf(output, "VIDEO_SEND_STREAM_CONFIG %" PRId64, event.log_time_ms());
104     fprintf(output, " ssrc=%u", event.config.local_ssrc);
105     fprintf(output, " rtx_ssrc=%u", event.config.rtx_ssrc);
106     PrintHeaderExtensionConfig(output, event.config.rtp_extensions);
107     fprintf(output, "\n");
108   };
109 
110   auto start_logging_handler = [&](const LoggedStartEvent& event) {
111     fprintf(output, "START_LOG %" PRId64 "\n", event.log_time_ms());
112   };
113 
114   auto stop_logging_handler = [&](const LoggedStopEvent& event) {
115     fprintf(output, "STOP_LOG %" PRId64 "\n", event.log_time_ms());
116   };
117 
118   auto alr_state_handler = [&](const LoggedAlrStateEvent& event) {
119     fprintf(output, "ALR_STATE %" PRId64 " in_alr=%u\n", event.log_time_ms(),
120             event.in_alr);
121   };
122 
123   auto audio_playout_handler = [&](const LoggedAudioPlayoutEvent& event) {
124     fprintf(output, "AUDIO_PLAYOUT %" PRId64 " ssrc=%u\n", event.log_time_ms(),
125             event.ssrc);
126   };
127 
128   auto audio_network_adaptation_handler =
129       [&](const LoggedAudioNetworkAdaptationEvent& event) {
130         fprintf(output, "AUDIO_NETWORK_ADAPTATION %" PRId64,
131                 event.log_time_ms());
132 
133         if (event.config.enable_dtx.has_value())
134           fprintf(output, " enable_dtx=%u", event.config.enable_dtx.value());
135         if (event.config.enable_fec.has_value())
136           fprintf(output, " enable_fec=%u", event.config.enable_fec.value());
137         if (event.config.bitrate_bps.has_value())
138           fprintf(output, " bitrate_bps=%d", event.config.bitrate_bps.value());
139         if (event.config.num_channels.has_value()) {
140           fprintf(output, " num_channels=%zu",
141                   event.config.num_channels.value());
142         }
143         if (event.config.frame_length_ms.has_value()) {
144           fprintf(output, " frame_length_ms=%d",
145                   event.config.frame_length_ms.value());
146         }
147         fprintf(output, " last_fl_change_increase=%u",
148                 event.config.last_fl_change_increase);
149         if (event.config.uplink_packet_loss_fraction.has_value()) {
150           fprintf(output, " uplink_packet_loss_fraction=%f",
151                   event.config.uplink_packet_loss_fraction.value());
152         }
153         fprintf(output, "\n");
154       };
155 
156   auto bwe_probe_cluster_created_handler =
157       [&](const LoggedBweProbeClusterCreatedEvent& event) {
158         fprintf(output,
159                 "BWE_PROBE_CREATED %" PRId64
160                 " id=%d bitrate_bps=%d min_packets=%u "
161                 "min_bytes=%u\n",
162                 event.log_time_ms(), event.id, event.bitrate_bps,
163                 event.min_packets, event.min_bytes);
164       };
165 
166   auto bwe_probe_failure_handler =
167       [&](const LoggedBweProbeFailureEvent& event) {
168         fprintf(output, "BWE_PROBE_FAILURE %" PRId64 " id=%d reason=%d\n",
169                 event.log_time_ms(), event.id, event.failure_reason);
170       };
171 
172   auto bwe_probe_success_handler =
173       [&](const LoggedBweProbeSuccessEvent& event) {
174         fprintf(output, "BWE_PROBE_SUCCESS %" PRId64 " id=%d bitrate_bps=%d\n",
175                 event.log_time_ms(), event.id, event.bitrate_bps);
176       };
177 
178   auto bwe_delay_update_handler = [&](const LoggedBweDelayBasedUpdate& event) {
179     static const std::map<BandwidthUsage, std::string> text{
180         {BandwidthUsage::kBwNormal, "NORMAL"},
181         {BandwidthUsage::kBwUnderusing, "UNDERUSING"},
182         {BandwidthUsage::kBwOverusing, "OVERUSING"},
183         {BandwidthUsage::kLast, "LAST"}};
184 
185     fprintf(output,
186             "BWE_DELAY_BASED %" PRId64 " bitrate_bps=%d detector_state=%s\n",
187             event.log_time_ms(), event.bitrate_bps,
188             text.at(event.detector_state).c_str());
189   };
190 
191   auto bwe_loss_update_handler = [&](const LoggedBweLossBasedUpdate& event) {
192     fprintf(output,
193             "BWE_LOSS_BASED %" PRId64
194             " bitrate_bps=%d fraction_lost=%d "
195             "expected_packets=%d\n",
196             event.log_time_ms(), event.bitrate_bps, event.fraction_lost,
197             event.expected_packets);
198   };
199 
200   auto dtls_transport_state_handler =
201       [&](const LoggedDtlsTransportState& event) {
202         fprintf(output, "DTLS_TRANSPORT_STATE %" PRId64 " state=%d\n",
203                 event.log_time_ms(), event.dtls_transport_state);
204       };
205 
206   auto dtls_transport_writable_handler =
207       [&](const LoggedDtlsWritableState& event) {
208         fprintf(output, "DTLS_WRITABLE %" PRId64 " writable=%u\n",
209                 event.log_time_ms(), event.writable);
210       };
211 
212   auto ice_candidate_pair_config_handler =
213       [&](const LoggedIceCandidatePairConfig& event) {
214         static const std::map<IceCandidatePairConfigType, std::string>
215             update_type_name{
216                 {IceCandidatePairConfigType::kAdded, "ADDED"},
217                 {IceCandidatePairConfigType::kUpdated, "UPDATED"},
218                 {IceCandidatePairConfigType::kDestroyed, "DESTROYED"},
219                 {IceCandidatePairConfigType::kSelected, "SELECTED"},
220                 {IceCandidatePairConfigType::kNumValues, "NUM_VALUES"}};
221 
222         static const std::map<IceCandidateType, std::string>
223             candidate_type_name{{IceCandidateType::kUnknown, "UNKNOWN"},
224                                 {IceCandidateType::kLocal, "LOCAL"},
225                                 {IceCandidateType::kStun, "STUN"},
226                                 {IceCandidateType::kPrflx, "PRFLX"},
227                                 {IceCandidateType::kRelay, "RELAY"},
228                                 {IceCandidateType::kNumValues, "NUM_VALUES"}};
229 
230         static const std::map<IceCandidatePairProtocol, std::string>
231             protocol_name{{IceCandidatePairProtocol::kUnknown, "UNKNOWN"},
232                           {IceCandidatePairProtocol::kUdp, "UDP"},
233                           {IceCandidatePairProtocol::kTcp, "TCP"},
234                           {IceCandidatePairProtocol::kSsltcp, "SSLTCP"},
235                           {IceCandidatePairProtocol::kTls, "TLS"},
236                           {IceCandidatePairProtocol::kNumValues, "NUM_VALUES"}};
237 
238         static const std::map<IceCandidatePairAddressFamily, std::string>
239             address_family_name{
240                 {IceCandidatePairAddressFamily::kUnknown, "UNKNOWN"},
241                 {IceCandidatePairAddressFamily::kIpv4, "IPv4"},
242                 {IceCandidatePairAddressFamily::kIpv6, "IPv6"},
243                 {IceCandidatePairAddressFamily::kNumValues, "NUM_VALUES"}};
244 
245         static const std::map<IceCandidateNetworkType, std::string>
246             network_type_name{
247                 {IceCandidateNetworkType::kUnknown, "UNKNOWN"},
248                 {IceCandidateNetworkType::kEthernet, "ETHERNET"},
249                 {IceCandidateNetworkType::kLoopback, "LOOPBACK"},
250                 {IceCandidateNetworkType::kWifi, "WIFI"},
251                 {IceCandidateNetworkType::kVpn, "VPN"},
252                 {IceCandidateNetworkType::kCellular, "CELLULAR"},
253                 {IceCandidateNetworkType::kNumValues, "NUM_VALUES"}};
254 
255         fprintf(output, "ICE_CANDIDATE_CONFIG %" PRId64, event.log_time_ms());
256         fprintf(output, " id=%u", event.candidate_pair_id);
257         fprintf(output, " type=%s", update_type_name.at(event.type).c_str());
258         fprintf(output, " local_network=%s",
259                 network_type_name.at(event.local_network_type).c_str());
260         fprintf(output, " local_address_family=%s",
261                 address_family_name.at(event.local_address_family).c_str());
262         fprintf(output, " local_candidate_type=%s",
263                 candidate_type_name.at(event.local_candidate_type).c_str());
264         fprintf(output, " local_relay_protocol=%s",
265                 protocol_name.at(event.local_relay_protocol).c_str());
266         fprintf(output, " remote_address=%s",
267                 address_family_name.at(event.remote_address_family).c_str());
268         fprintf(output, " remote_candidate_type=%s",
269                 candidate_type_name.at(event.remote_candidate_type).c_str());
270         fprintf(output, " candidate_pair_protocol=%s",
271                 protocol_name.at(event.candidate_pair_protocol).c_str());
272         fprintf(output, "\n");
273       };
274 
275   auto ice_candidate_pair_event_handler =
276       [&](const LoggedIceCandidatePairEvent& event) {
277         static const std::map<IceCandidatePairEventType, std::string>
278             check_type_name{
279                 {IceCandidatePairEventType::kCheckSent, "CHECK_SENT"},
280                 {IceCandidatePairEventType::kCheckReceived, "CHECK_RECEIVED"},
281                 {IceCandidatePairEventType::kCheckResponseSent,
282                  "CHECK_RESPONSE_SENT"},
283                 {IceCandidatePairEventType::kCheckResponseReceived,
284                  "CHECK_RESPONSE_RECEIVED"},
285                 {IceCandidatePairEventType::kNumValues, "NUM_VALUES"}};
286 
287         fprintf(output, "ICE_CANDIDATE_UPDATE %" PRId64, event.log_time_ms());
288         fprintf(output, " id=%u", event.candidate_pair_id);
289         fprintf(output, " type=%s", check_type_name.at(event.type).c_str());
290         fprintf(output, " transaction_id=%u", event.transaction_id);
291         fprintf(output, "\n");
292       };
293 
294   auto route_change_handler = [&](const LoggedRouteChangeEvent& event) {
295     fprintf(output, "ROUTE_CHANGE %" PRId64 " connected=%u overhead=%u\n",
296             event.log_time_ms(), event.connected, event.overhead);
297   };
298 
299   auto remote_estimate_handler = [&](const LoggedRemoteEstimateEvent& event) {
300     fprintf(output, "REMOTE_ESTIMATE %" PRId64, event.log_time_ms());
301     if (event.link_capacity_lower.has_value()) {
302       fprintf(output, " link_capacity_lower_kbps=%" PRId64,
303               event.link_capacity_lower.value().kbps());
304     }
305     if (event.link_capacity_upper.has_value()) {
306       fprintf(output, " link_capacity_upper_kbps=%" PRId64,
307               event.link_capacity_upper.value().kbps());
308     }
309     fprintf(output, "\n");
310   };
311 
312   auto incoming_rtp_packet_handler = [&](const LoggedRtpPacketIncoming& event) {
313     fprintf(output, "RTP_IN %" PRId64, event.log_time_ms());
314     fprintf(output, " ssrc=%u", event.rtp.header.ssrc);
315     fprintf(output, " seq_no=%u", event.rtp.header.sequenceNumber);
316     fprintf(output, " marker=%u", event.rtp.header.markerBit);
317     fprintf(output, " pt=%u", event.rtp.header.payloadType);
318     fprintf(output, " timestamp=%u", event.rtp.header.timestamp);
319     if (event.rtp.header.extension.hasAbsoluteSendTime) {
320       fprintf(output, " abs_send_time=%u",
321               event.rtp.header.extension.absoluteSendTime);
322     }
323     if (event.rtp.header.extension.hasTransmissionTimeOffset) {
324       fprintf(output, " transmission_offset=%d",
325               event.rtp.header.extension.transmissionTimeOffset);
326     }
327     if (event.rtp.header.extension.hasAudioLevel) {
328       fprintf(output, " voice_activity=%d",
329               event.rtp.header.extension.voiceActivity);
330       fprintf(output, " audio_level=%u", event.rtp.header.extension.audioLevel);
331     }
332     if (event.rtp.header.extension.hasVideoRotation) {
333       fprintf(output, " video_rotation=%d",
334               event.rtp.header.extension.videoRotation);
335     }
336     if (event.rtp.header.extension.hasTransportSequenceNumber) {
337       fprintf(output, " transport_seq_no=%u",
338               event.rtp.header.extension.transportSequenceNumber);
339     }
340     fprintf(output, " header_length=%zu", event.rtp.header_length);
341     fprintf(output, " padding_length=%zu", event.rtp.header.paddingLength);
342     fprintf(output, " total_length=%zu", event.rtp.total_length);
343     fprintf(output, "\n");
344   };
345 
346   auto outgoing_rtp_packet_handler = [&](const LoggedRtpPacketOutgoing& event) {
347     fprintf(output, "RTP_OUT %" PRId64, event.log_time_ms());
348     fprintf(output, " ssrc=%u", event.rtp.header.ssrc);
349     fprintf(output, " seq_no=%u", event.rtp.header.sequenceNumber);
350     fprintf(output, " marker=%u", event.rtp.header.markerBit);
351     fprintf(output, " pt=%u", event.rtp.header.payloadType);
352     fprintf(output, " timestamp=%u", event.rtp.header.timestamp);
353     if (event.rtp.header.extension.hasAbsoluteSendTime) {
354       fprintf(output, " abs_send_time=%u",
355               event.rtp.header.extension.absoluteSendTime);
356     }
357     if (event.rtp.header.extension.hasTransmissionTimeOffset) {
358       fprintf(output, " transmission_offset=%d",
359               event.rtp.header.extension.transmissionTimeOffset);
360     }
361     if (event.rtp.header.extension.hasAudioLevel) {
362       fprintf(output, " voice_activity=%d",
363               event.rtp.header.extension.voiceActivity);
364       fprintf(output, " audio_level=%u", event.rtp.header.extension.audioLevel);
365     }
366     if (event.rtp.header.extension.hasVideoRotation) {
367       fprintf(output, " video_rotation=%d",
368               event.rtp.header.extension.videoRotation);
369     }
370     if (event.rtp.header.extension.hasTransportSequenceNumber) {
371       fprintf(output, " transport_seq_no=%u",
372               event.rtp.header.extension.transportSequenceNumber);
373     }
374     fprintf(output, " header_length=%zu", event.rtp.header_length);
375     fprintf(output, " padding_length=%zu", event.rtp.header.paddingLength);
376     fprintf(output, " total_length=%zu", event.rtp.total_length);
377     fprintf(output, "\n");
378   };
379 
380   auto incoming_rtcp_packet_handler =
381       [&](const LoggedRtcpPacketIncoming& event) {
382         fprintf(output, "RTCP_IN %" PRId64 " <contents omitted>\n",
383                 event.log_time_ms());
384       };
385 
386   auto outgoing_rtcp_packet_handler =
387       [&](const LoggedRtcpPacketOutgoing& event) {
388         fprintf(output, "RTCP_OUT %" PRId64 " <contents omitted>\n",
389                 event.log_time_ms());
390       };
391 
392   auto generic_packet_received_handler =
393       [&](const LoggedGenericPacketReceived& event) {
394         fprintf(output,
395                 "GENERIC_PACKET_RECV %" PRId64 " packet_no=%" PRId64
396                 " length=%d\n",
397                 event.log_time_ms(), event.packet_number, event.packet_length);
398       };
399 
400   auto generic_packet_sent_handler = [&](const LoggedGenericPacketSent& event) {
401     fprintf(output,
402             "GENERIC_PACKET_SENT %" PRId64 " packet_no=%" PRId64
403             " overhead_length=%zu "
404             "payload_length=%zu padding_length=%zu\n",
405             event.log_time_ms(), event.packet_number, event.overhead_length,
406             event.payload_length, event.padding_length);
407   };
408 
409   auto generic_ack_received_handler =
410       [&](const LoggedGenericAckReceived& event) {
411         fprintf(output, "GENERIC_ACK_RECV %" PRId64 " <contents omitted>\n",
412                 event.log_time_ms());
413       };
414 
415   auto decoded_frame_handler = [&](const LoggedFrameDecoded& event) {
416     static const std::map<VideoCodecType, std::string> codec_name{
417         {VideoCodecType::kVideoCodecGeneric, "GENERIC"},
418         {VideoCodecType::kVideoCodecVP8, "VP8"},
419         {VideoCodecType::kVideoCodecVP9, "VP9"},
420         {VideoCodecType::kVideoCodecAV1, "AV1"},
421         {VideoCodecType::kVideoCodecH264, "H264"},
422         {VideoCodecType::kVideoCodecMultiplex, "MULTIPLEX"}};
423 
424     fprintf(output,
425             "FRAME_DECODED %" PRId64 " render_time=%" PRId64
426             " ssrc=%u width=%d height=%d "
427             "codec=%s qp=%u\n",
428             event.log_time_ms(), event.render_time_ms, event.ssrc, event.width,
429             event.height, codec_name.at(event.codec).c_str(), event.qp);
430   };
431 
432   RtcEventProcessor processor;
433 
434   // Stream configs
435   processor.AddEvents(parsed_log.audio_recv_configs(),
436                       audio_recv_stream_handler);
437   processor.AddEvents(parsed_log.audio_send_configs(),
438                       audio_send_stream_handler);
439   processor.AddEvents(parsed_log.video_recv_configs(),
440                       video_recv_stream_handler);
441   processor.AddEvents(parsed_log.video_send_configs(),
442                       video_send_stream_handler);
443 
444   // Start and stop
445   processor.AddEvents(parsed_log.start_log_events(), start_logging_handler);
446   processor.AddEvents(parsed_log.stop_log_events(), stop_logging_handler);
447 
448   // Audio
449   for (const auto& kv : parsed_log.audio_playout_events()) {
450     processor.AddEvents(kv.second, audio_playout_handler);
451   }
452   processor.AddEvents(parsed_log.audio_network_adaptation_events(),
453                       audio_network_adaptation_handler);
454 
455   // Bandwidth estimation and pacing
456   processor.AddEvents(parsed_log.alr_state_events(), alr_state_handler);
457   processor.AddEvents(parsed_log.bwe_probe_cluster_created_events(),
458                       bwe_probe_cluster_created_handler);
459   processor.AddEvents(parsed_log.bwe_probe_failure_events(),
460                       bwe_probe_failure_handler);
461   processor.AddEvents(parsed_log.bwe_probe_success_events(),
462                       bwe_probe_success_handler);
463   processor.AddEvents(parsed_log.bwe_delay_updates(), bwe_delay_update_handler);
464   processor.AddEvents(parsed_log.bwe_loss_updates(), bwe_loss_update_handler);
465   processor.AddEvents(parsed_log.remote_estimate_events(),
466                       remote_estimate_handler);
467 
468   // Connectivity
469   processor.AddEvents(parsed_log.dtls_transport_states(),
470                       dtls_transport_state_handler);
471   processor.AddEvents(parsed_log.dtls_writable_states(),
472                       dtls_transport_writable_handler);
473   processor.AddEvents(parsed_log.ice_candidate_pair_configs(),
474                       ice_candidate_pair_config_handler);
475   processor.AddEvents(parsed_log.ice_candidate_pair_events(),
476                       ice_candidate_pair_event_handler);
477   processor.AddEvents(parsed_log.route_change_events(), route_change_handler);
478 
479   // RTP
480   for (const auto& stream : parsed_log.incoming_rtp_packets_by_ssrc()) {
481     processor.AddEvents(stream.incoming_packets, incoming_rtp_packet_handler);
482   }
483   for (const auto& stream : parsed_log.outgoing_rtp_packets_by_ssrc()) {
484     processor.AddEvents(stream.outgoing_packets, outgoing_rtp_packet_handler);
485   }
486 
487   // RTCP
488   processor.AddEvents(parsed_log.incoming_rtcp_packets(),
489                       incoming_rtcp_packet_handler);
490   processor.AddEvents(parsed_log.outgoing_rtcp_packets(),
491                       outgoing_rtcp_packet_handler);
492 
493   // Generic packets
494   processor.AddEvents(parsed_log.generic_packets_received(),
495                       generic_packet_received_handler);
496   processor.AddEvents(parsed_log.generic_packets_sent(),
497                       generic_packet_sent_handler);
498   processor.AddEvents(parsed_log.generic_acks_received(),
499                       generic_ack_received_handler);
500 
501   // Video frames
502   for (const auto& kv : parsed_log.decoded_frames()) {
503     processor.AddEvents(kv.second, decoded_frame_handler);
504   }
505 
506   processor.ProcessEventsInOrder();
507 
508   return true;
509 }
510 
511 }  // namespace webrtc
512