diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/rtc_tools/rtc_event_log_to_text | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/rtc_tools/rtc_event_log_to_text')
4 files changed, 640 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/OWNERS b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/OWNERS new file mode 100644 index 0000000000..f1a86c6d31 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/OWNERS @@ -0,0 +1 @@ +terelius@webrtc.org diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/converter.cc b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/converter.cc new file mode 100644 index 0000000000..6bd3458a6f --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/converter.cc @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_tools/rtc_event_log_to_text/converter.h" + +#include <inttypes.h> + +#include <map> +#include <vector> + +#include "logging/rtc_event_log/events/logged_rtp_rtcp.h" +#include "logging/rtc_event_log/events/rtc_event_alr_state.h" +#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h" +#include "logging/rtc_event_log/events/rtc_event_audio_playout.h" +#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_begin_log.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h" +#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h" +#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h" +#include "logging/rtc_event_log/events/rtc_event_end_log.h" +#include "logging/rtc_event_log/events/rtc_event_frame_decoded.h" +#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h" +#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h" +#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h" +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h" +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" +#include "logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h" +#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h" +#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h" +#include "logging/rtc_event_log/events/rtc_event_route_change.h" +#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h" +#include "logging/rtc_event_log/rtc_event_log_parser.h" +#include "logging/rtc_event_log/rtc_event_processor.h" +#include "logging/rtc_event_log/rtc_stream_config.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace { + +void PrintHeaderExtensionConfig( + FILE* output, + const std::vector<RtpExtension>& rtp_extensions) { + if (rtp_extensions.empty()) + return; + fprintf(output, " extension_map="); + for (const RtpExtension& extension : rtp_extensions) { + fprintf(output, "{uri:%s,id:%d}", extension.uri.c_str(), extension.id); + } +} + +} // namespace + +bool Convert(std::string inputfile, + FILE* output, + ParsedRtcEventLog::UnconfiguredHeaderExtensions + handle_unconfigured_extensions) { + ParsedRtcEventLog parsed_log(handle_unconfigured_extensions, + /*allow_incomplete_logs=*/true); + + auto status = parsed_log.ParseFile(inputfile); + if (!status.ok()) { + RTC_LOG(LS_ERROR) << "Failed to parse " << inputfile << ": " + << status.message(); + return false; + } + + auto audio_recv_stream_handler = [&](const LoggedAudioRecvConfig& event) { + fprintf(output, "AUDIO_RECV_STREAM_CONFIG %" PRId64, event.log_time_ms()); + fprintf(output, " remote_ssrc=%u", event.config.remote_ssrc); + fprintf(output, " local_ssrc=%u", event.config.local_ssrc); + PrintHeaderExtensionConfig(output, event.config.rtp_extensions); + fprintf(output, "\n"); + }; + + auto audio_send_stream_handler = [&](const LoggedAudioSendConfig& event) { + fprintf(output, "AUDIO_SEND_STREAM_CONFIG %" PRId64, event.log_time_ms()); + fprintf(output, " ssrc=%u", event.config.local_ssrc); + PrintHeaderExtensionConfig(output, event.config.rtp_extensions); + fprintf(output, "\n"); + }; + + auto video_recv_stream_handler = [&](const LoggedVideoRecvConfig& event) { + fprintf(output, "VIDEO_RECV_STREAM_CONFIG %" PRId64, event.log_time_ms()); + fprintf(output, " remote_ssrc=%u", event.config.remote_ssrc); + fprintf(output, " local_ssrc=%u", event.config.local_ssrc); + fprintf(output, " rtx_ssrc=%u", event.config.rtx_ssrc); + PrintHeaderExtensionConfig(output, event.config.rtp_extensions); + fprintf(output, "\n"); + }; + + auto video_send_stream_handler = [&](const LoggedVideoSendConfig& event) { + fprintf(output, "VIDEO_SEND_STREAM_CONFIG %" PRId64, event.log_time_ms()); + fprintf(output, " ssrc=%u", event.config.local_ssrc); + fprintf(output, " rtx_ssrc=%u", event.config.rtx_ssrc); + PrintHeaderExtensionConfig(output, event.config.rtp_extensions); + fprintf(output, "\n"); + }; + + auto start_logging_handler = [&](const LoggedStartEvent& event) { + fprintf(output, "START_LOG %" PRId64 "\n", event.log_time_ms()); + }; + + auto stop_logging_handler = [&](const LoggedStopEvent& event) { + fprintf(output, "STOP_LOG %" PRId64 "\n", event.log_time_ms()); + }; + + auto alr_state_handler = [&](const LoggedAlrStateEvent& event) { + fprintf(output, "ALR_STATE %" PRId64 " in_alr=%u\n", event.log_time_ms(), + event.in_alr); + }; + + auto audio_playout_handler = [&](const LoggedAudioPlayoutEvent& event) { + fprintf(output, "AUDIO_PLAYOUT %" PRId64 " ssrc=%u\n", event.log_time_ms(), + event.ssrc); + }; + + auto neteq_set_minimum_delay_handler = + [&](const LoggedNetEqSetMinimumDelayEvent& event) { + fprintf(output, + "NETEQ_SET_MINIMUM_DELAY %" PRId64 + " remote_ssrc=%u minimum_delay=%d\n", + event.log_time_ms(), event.remote_ssrc, event.minimum_delay_ms); + }; + + auto audio_network_adaptation_handler = + [&](const LoggedAudioNetworkAdaptationEvent& event) { + fprintf(output, "AUDIO_NETWORK_ADAPTATION %" PRId64, + event.log_time_ms()); + + if (event.config.enable_dtx.has_value()) + fprintf(output, " enable_dtx=%u", event.config.enable_dtx.value()); + if (event.config.enable_fec.has_value()) + fprintf(output, " enable_fec=%u", event.config.enable_fec.value()); + if (event.config.bitrate_bps.has_value()) + fprintf(output, " bitrate_bps=%d", event.config.bitrate_bps.value()); + if (event.config.num_channels.has_value()) { + fprintf(output, " num_channels=%zu", + event.config.num_channels.value()); + } + if (event.config.frame_length_ms.has_value()) { + fprintf(output, " frame_length_ms=%d", + event.config.frame_length_ms.value()); + } + fprintf(output, " last_fl_change_increase=%u", + event.config.last_fl_change_increase); + if (event.config.uplink_packet_loss_fraction.has_value()) { + fprintf(output, " uplink_packet_loss_fraction=%f", + event.config.uplink_packet_loss_fraction.value()); + } + fprintf(output, "\n"); + }; + + auto bwe_probe_cluster_created_handler = + [&](const LoggedBweProbeClusterCreatedEvent& event) { + fprintf(output, + "BWE_PROBE_CREATED %" PRId64 + " id=%d bitrate_bps=%d min_packets=%u " + "min_bytes=%u\n", + event.log_time_ms(), event.id, event.bitrate_bps, + event.min_packets, event.min_bytes); + }; + + auto bwe_probe_failure_handler = + [&](const LoggedBweProbeFailureEvent& event) { + fprintf(output, "BWE_PROBE_FAILURE %" PRId64 " id=%d reason=%d\n", + event.log_time_ms(), event.id, event.failure_reason); + }; + + auto bwe_probe_success_handler = + [&](const LoggedBweProbeSuccessEvent& event) { + fprintf(output, "BWE_PROBE_SUCCESS %" PRId64 " id=%d bitrate_bps=%d\n", + event.log_time_ms(), event.id, event.bitrate_bps); + }; + + auto bwe_delay_update_handler = [&](const LoggedBweDelayBasedUpdate& event) { + static const std::map<BandwidthUsage, std::string> text{ + {BandwidthUsage::kBwNormal, "NORMAL"}, + {BandwidthUsage::kBwUnderusing, "UNDERUSING"}, + {BandwidthUsage::kBwOverusing, "OVERUSING"}, + {BandwidthUsage::kLast, "LAST"}}; + + fprintf(output, + "BWE_DELAY_BASED %" PRId64 " bitrate_bps=%d detector_state=%s\n", + event.log_time_ms(), event.bitrate_bps, + text.at(event.detector_state).c_str()); + }; + + auto bwe_loss_update_handler = [&](const LoggedBweLossBasedUpdate& event) { + fprintf(output, + "BWE_LOSS_BASED %" PRId64 + " bitrate_bps=%d fraction_lost=%d " + "expected_packets=%d\n", + event.log_time_ms(), event.bitrate_bps, event.fraction_lost, + event.expected_packets); + }; + + auto dtls_transport_state_handler = + [&](const LoggedDtlsTransportState& event) { + fprintf(output, "DTLS_TRANSPORT_STATE %" PRId64 " state=%d\n", + event.log_time_ms(), event.dtls_transport_state); + }; + + auto dtls_transport_writable_handler = + [&](const LoggedDtlsWritableState& event) { + fprintf(output, "DTLS_WRITABLE %" PRId64 " writable=%u\n", + event.log_time_ms(), event.writable); + }; + + auto ice_candidate_pair_config_handler = + [&](const LoggedIceCandidatePairConfig& event) { + static const std::map<IceCandidatePairConfigType, std::string> + update_type_name{ + {IceCandidatePairConfigType::kAdded, "ADDED"}, + {IceCandidatePairConfigType::kUpdated, "UPDATED"}, + {IceCandidatePairConfigType::kDestroyed, "DESTROYED"}, + {IceCandidatePairConfigType::kSelected, "SELECTED"}, + {IceCandidatePairConfigType::kNumValues, "NUM_VALUES"}}; + + static const std::map<IceCandidateType, std::string> + candidate_type_name{{IceCandidateType::kUnknown, "UNKNOWN"}, + {IceCandidateType::kLocal, "LOCAL"}, + {IceCandidateType::kStun, "STUN"}, + {IceCandidateType::kPrflx, "PRFLX"}, + {IceCandidateType::kRelay, "RELAY"}, + {IceCandidateType::kNumValues, "NUM_VALUES"}}; + + static const std::map<IceCandidatePairProtocol, std::string> + protocol_name{{IceCandidatePairProtocol::kUnknown, "UNKNOWN"}, + {IceCandidatePairProtocol::kUdp, "UDP"}, + {IceCandidatePairProtocol::kTcp, "TCP"}, + {IceCandidatePairProtocol::kSsltcp, "SSLTCP"}, + {IceCandidatePairProtocol::kTls, "TLS"}, + {IceCandidatePairProtocol::kNumValues, "NUM_VALUES"}}; + + static const std::map<IceCandidatePairAddressFamily, std::string> + address_family_name{ + {IceCandidatePairAddressFamily::kUnknown, "UNKNOWN"}, + {IceCandidatePairAddressFamily::kIpv4, "IPv4"}, + {IceCandidatePairAddressFamily::kIpv6, "IPv6"}, + {IceCandidatePairAddressFamily::kNumValues, "NUM_VALUES"}}; + + static const std::map<IceCandidateNetworkType, std::string> + network_type_name{ + {IceCandidateNetworkType::kUnknown, "UNKNOWN"}, + {IceCandidateNetworkType::kEthernet, "ETHERNET"}, + {IceCandidateNetworkType::kLoopback, "LOOPBACK"}, + {IceCandidateNetworkType::kWifi, "WIFI"}, + {IceCandidateNetworkType::kVpn, "VPN"}, + {IceCandidateNetworkType::kCellular, "CELLULAR"}, + {IceCandidateNetworkType::kNumValues, "NUM_VALUES"}}; + + fprintf(output, "ICE_CANDIDATE_CONFIG %" PRId64, event.log_time_ms()); + fprintf(output, " id=%u", event.candidate_pair_id); + fprintf(output, " type=%s", update_type_name.at(event.type).c_str()); + fprintf(output, " local_network=%s", + network_type_name.at(event.local_network_type).c_str()); + fprintf(output, " local_address_family=%s", + address_family_name.at(event.local_address_family).c_str()); + fprintf(output, " local_candidate_type=%s", + candidate_type_name.at(event.local_candidate_type).c_str()); + fprintf(output, " local_relay_protocol=%s", + protocol_name.at(event.local_relay_protocol).c_str()); + fprintf(output, " remote_address=%s", + address_family_name.at(event.remote_address_family).c_str()); + fprintf(output, " remote_candidate_type=%s", + candidate_type_name.at(event.remote_candidate_type).c_str()); + fprintf(output, " candidate_pair_protocol=%s", + protocol_name.at(event.candidate_pair_protocol).c_str()); + fprintf(output, "\n"); + }; + + auto ice_candidate_pair_event_handler = + [&](const LoggedIceCandidatePairEvent& event) { + static const std::map<IceCandidatePairEventType, std::string> + check_type_name{ + {IceCandidatePairEventType::kCheckSent, "CHECK_SENT"}, + {IceCandidatePairEventType::kCheckReceived, "CHECK_RECEIVED"}, + {IceCandidatePairEventType::kCheckResponseSent, + "CHECK_RESPONSE_SENT"}, + {IceCandidatePairEventType::kCheckResponseReceived, + "CHECK_RESPONSE_RECEIVED"}, + {IceCandidatePairEventType::kNumValues, "NUM_VALUES"}}; + + fprintf(output, "ICE_CANDIDATE_UPDATE %" PRId64, event.log_time_ms()); + fprintf(output, " id=%u", event.candidate_pair_id); + fprintf(output, " type=%s", check_type_name.at(event.type).c_str()); + fprintf(output, " transaction_id=%u", event.transaction_id); + fprintf(output, "\n"); + }; + + auto route_change_handler = [&](const LoggedRouteChangeEvent& event) { + fprintf(output, "ROUTE_CHANGE %" PRId64 " connected=%u overhead=%u\n", + event.log_time_ms(), event.connected, event.overhead); + }; + + auto remote_estimate_handler = [&](const LoggedRemoteEstimateEvent& event) { + fprintf(output, "REMOTE_ESTIMATE %" PRId64, event.log_time_ms()); + if (event.link_capacity_lower.has_value()) { + fprintf(output, " link_capacity_lower_kbps=%" PRId64, + event.link_capacity_lower.value().kbps()); + } + if (event.link_capacity_upper.has_value()) { + fprintf(output, " link_capacity_upper_kbps=%" PRId64, + event.link_capacity_upper.value().kbps()); + } + fprintf(output, "\n"); + }; + + auto incoming_rtp_packet_handler = [&](const LoggedRtpPacketIncoming& event) { + fprintf(output, "RTP_IN %" PRId64, event.log_time_ms()); + fprintf(output, " ssrc=%u", event.rtp.header.ssrc); + fprintf(output, " seq_no=%u", event.rtp.header.sequenceNumber); + fprintf(output, " marker=%u", event.rtp.header.markerBit); + fprintf(output, " pt=%u", event.rtp.header.payloadType); + fprintf(output, " timestamp=%u", event.rtp.header.timestamp); + if (event.rtp.header.extension.hasAbsoluteSendTime) { + fprintf(output, " abs_send_time=%u", + event.rtp.header.extension.absoluteSendTime); + } + if (event.rtp.header.extension.hasTransmissionTimeOffset) { + fprintf(output, " transmission_offset=%d", + event.rtp.header.extension.transmissionTimeOffset); + } + if (event.rtp.header.extension.hasAudioLevel) { + fprintf(output, " voice_activity=%d", + event.rtp.header.extension.voiceActivity); + fprintf(output, " audio_level=%u", event.rtp.header.extension.audioLevel); + } + if (event.rtp.header.extension.hasVideoRotation) { + fprintf(output, " video_rotation=%d", + event.rtp.header.extension.videoRotation); + } + if (event.rtp.header.extension.hasTransportSequenceNumber) { + fprintf(output, " transport_seq_no=%u", + event.rtp.header.extension.transportSequenceNumber); + } + fprintf(output, " header_length=%zu", event.rtp.header_length); + fprintf(output, " padding_length=%zu", event.rtp.header.paddingLength); + fprintf(output, " total_length=%zu", event.rtp.total_length); + fprintf(output, "\n"); + }; + + auto outgoing_rtp_packet_handler = [&](const LoggedRtpPacketOutgoing& event) { + fprintf(output, "RTP_OUT %" PRId64, event.log_time_ms()); + fprintf(output, " ssrc=%u", event.rtp.header.ssrc); + fprintf(output, " seq_no=%u", event.rtp.header.sequenceNumber); + fprintf(output, " marker=%u", event.rtp.header.markerBit); + fprintf(output, " pt=%u", event.rtp.header.payloadType); + fprintf(output, " timestamp=%u", event.rtp.header.timestamp); + if (event.rtp.header.extension.hasAbsoluteSendTime) { + fprintf(output, " abs_send_time=%u", + event.rtp.header.extension.absoluteSendTime); + } + if (event.rtp.header.extension.hasTransmissionTimeOffset) { + fprintf(output, " transmission_offset=%d", + event.rtp.header.extension.transmissionTimeOffset); + } + if (event.rtp.header.extension.hasAudioLevel) { + fprintf(output, " voice_activity=%d", + event.rtp.header.extension.voiceActivity); + fprintf(output, " audio_level=%u", event.rtp.header.extension.audioLevel); + } + if (event.rtp.header.extension.hasVideoRotation) { + fprintf(output, " video_rotation=%d", + event.rtp.header.extension.videoRotation); + } + if (event.rtp.header.extension.hasTransportSequenceNumber) { + fprintf(output, " transport_seq_no=%u", + event.rtp.header.extension.transportSequenceNumber); + } + fprintf(output, " header_length=%zu", event.rtp.header_length); + fprintf(output, " padding_length=%zu", event.rtp.header.paddingLength); + fprintf(output, " total_length=%zu", event.rtp.total_length); + fprintf(output, "\n"); + }; + + auto incoming_rtcp_packet_handler = + [&](const LoggedRtcpPacketIncoming& event) { + fprintf(output, "RTCP_IN %" PRId64 " <contents omitted>\n", + event.log_time_ms()); + }; + + auto outgoing_rtcp_packet_handler = + [&](const LoggedRtcpPacketOutgoing& event) { + fprintf(output, "RTCP_OUT %" PRId64 " <contents omitted>\n", + event.log_time_ms()); + }; + + auto generic_packet_received_handler = + [&](const LoggedGenericPacketReceived& event) { + fprintf(output, + "GENERIC_PACKET_RECV %" PRId64 " packet_no=%" PRId64 + " length=%d\n", + event.log_time_ms(), event.packet_number, event.packet_length); + }; + + auto generic_packet_sent_handler = [&](const LoggedGenericPacketSent& event) { + fprintf(output, + "GENERIC_PACKET_SENT %" PRId64 " packet_no=%" PRId64 + " overhead_length=%zu " + "payload_length=%zu padding_length=%zu\n", + event.log_time_ms(), event.packet_number, event.overhead_length, + event.payload_length, event.padding_length); + }; + + auto generic_ack_received_handler = + [&](const LoggedGenericAckReceived& event) { + fprintf(output, "GENERIC_ACK_RECV %" PRId64 " <contents omitted>\n", + event.log_time_ms()); + }; + + auto decoded_frame_handler = [&](const LoggedFrameDecoded& event) { + static const std::map<VideoCodecType, std::string> codec_name{ + {VideoCodecType::kVideoCodecGeneric, "GENERIC"}, + {VideoCodecType::kVideoCodecVP8, "VP8"}, + {VideoCodecType::kVideoCodecVP9, "VP9"}, + {VideoCodecType::kVideoCodecAV1, "AV1"}, + {VideoCodecType::kVideoCodecH264, "H264"}, + {VideoCodecType::kVideoCodecMultiplex, "MULTIPLEX"}}; + + fprintf(output, + "FRAME_DECODED %" PRId64 " render_time=%" PRId64 + " ssrc=%u width=%d height=%d " + "codec=%s qp=%u\n", + event.log_time_ms(), event.render_time_ms, event.ssrc, event.width, + event.height, codec_name.at(event.codec).c_str(), event.qp); + }; + + RtcEventProcessor processor; + + // Stream configs + processor.AddEvents(parsed_log.audio_recv_configs(), + audio_recv_stream_handler); + processor.AddEvents(parsed_log.audio_send_configs(), + audio_send_stream_handler); + processor.AddEvents(parsed_log.video_recv_configs(), + video_recv_stream_handler); + processor.AddEvents(parsed_log.video_send_configs(), + video_send_stream_handler); + + // Start and stop + processor.AddEvents(parsed_log.start_log_events(), start_logging_handler); + processor.AddEvents(parsed_log.stop_log_events(), stop_logging_handler); + + // Audio + for (const auto& kv : parsed_log.audio_playout_events()) { + processor.AddEvents(kv.second, audio_playout_handler); + } + + for (const auto& kv : parsed_log.neteq_set_minimum_delay_events()) { + processor.AddEvents(kv.second, neteq_set_minimum_delay_handler); + } + + processor.AddEvents(parsed_log.audio_network_adaptation_events(), + audio_network_adaptation_handler); + + // Bandwidth estimation and pacing + processor.AddEvents(parsed_log.alr_state_events(), alr_state_handler); + processor.AddEvents(parsed_log.bwe_probe_cluster_created_events(), + bwe_probe_cluster_created_handler); + processor.AddEvents(parsed_log.bwe_probe_failure_events(), + bwe_probe_failure_handler); + processor.AddEvents(parsed_log.bwe_probe_success_events(), + bwe_probe_success_handler); + processor.AddEvents(parsed_log.bwe_delay_updates(), bwe_delay_update_handler); + processor.AddEvents(parsed_log.bwe_loss_updates(), bwe_loss_update_handler); + processor.AddEvents(parsed_log.remote_estimate_events(), + remote_estimate_handler); + + // Connectivity + processor.AddEvents(parsed_log.dtls_transport_states(), + dtls_transport_state_handler); + processor.AddEvents(parsed_log.dtls_writable_states(), + dtls_transport_writable_handler); + processor.AddEvents(parsed_log.ice_candidate_pair_configs(), + ice_candidate_pair_config_handler); + processor.AddEvents(parsed_log.ice_candidate_pair_events(), + ice_candidate_pair_event_handler); + processor.AddEvents(parsed_log.route_change_events(), route_change_handler); + + // RTP + for (const auto& stream : parsed_log.incoming_rtp_packets_by_ssrc()) { + processor.AddEvents(stream.incoming_packets, incoming_rtp_packet_handler); + } + for (const auto& stream : parsed_log.outgoing_rtp_packets_by_ssrc()) { + processor.AddEvents(stream.outgoing_packets, outgoing_rtp_packet_handler); + } + + // RTCP + processor.AddEvents(parsed_log.incoming_rtcp_packets(), + incoming_rtcp_packet_handler); + processor.AddEvents(parsed_log.outgoing_rtcp_packets(), + outgoing_rtcp_packet_handler); + + // Generic packets + processor.AddEvents(parsed_log.generic_packets_received(), + generic_packet_received_handler); + processor.AddEvents(parsed_log.generic_packets_sent(), + generic_packet_sent_handler); + processor.AddEvents(parsed_log.generic_acks_received(), + generic_ack_received_handler); + + // Video frames + for (const auto& kv : parsed_log.decoded_frames()) { + processor.AddEvents(kv.second, decoded_frame_handler); + } + + processor.ProcessEventsInOrder(); + + return true; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/converter.h b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/converter.h new file mode 100644 index 0000000000..fbcee7c196 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/converter.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_TOOLS_RTC_EVENT_LOG_TO_TEXT_CONVERTER_H_ +#define RTC_TOOLS_RTC_EVENT_LOG_TO_TEXT_CONVERTER_H_ + +#include <stdio.h> + +#include <string> + +#include "absl/base/attributes.h" +#include "logging/rtc_event_log/rtc_event_log_parser.h" + +namespace webrtc { + +// Parses events from file `inputfile` and prints human readable text +// representations to `output`. The output is sorted by log time. +// `handle_unconfigured_extensions` controls the policy for parsing RTP +// header extensions if the log doesn't contain a mapping between the +// header extensions and numerical IDs. +ABSL_MUST_USE_RESULT bool Convert( + std::string inputfile, + FILE* output, + ParsedRtcEventLog::UnconfiguredHeaderExtensions + handle_unconfigured_extensions); + +} // namespace webrtc + +#endif // RTC_TOOLS_RTC_EVENT_LOG_TO_TEXT_CONVERTER_H_ diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/main.cc b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/main.cc new file mode 100644 index 0000000000..e4937b1327 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_to_text/main.cc @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdio.h> + +#include <string> +#include <vector> + +#include "absl/flags/flag.h" +#include "absl/flags/parse.h" +#include "absl/flags/usage.h" +#include "absl/strings/string_view.h" +#include "logging/rtc_event_log/rtc_event_log_parser.h" +#include "rtc_base/logging.h" +#include "rtc_tools/rtc_event_log_to_text/converter.h" + +ABSL_FLAG(bool, + parse_unconfigured_header_extensions, + true, + "Attempt to parse unconfigured header extensions using the default " + "WebRTC mapping. This can give very misleading results if the " + "application negotiates a different mapping."); + +// Prints an RTC event log as human readable text with one line per event. +// Note that the RTC event log text format isn't an API. Prefer to build +// tools directly on the parser (logging/rtc_event_log/rtc_event_log_parser.cc). +int main(int argc, char* argv[]) { + absl::SetProgramUsageMessage( + "A tool for converting WebRTC event logs to text.\n" + "The events are sorted by log time and printed\n" + "with one event per line, using the following format:\n" + "<EVENT_TYPE> <log_time_ms> <field1>=<value1> <field2>=<value2> ...\n" + "\n" + "Example usage:\n" + "./rtc_event_log_to_text <inputfile> <outputfile>\n" + "./rtc_event_log_to_text <inputfile>\n" + "If no output file is specified, the output is written to stdout\n"); + std::vector<char*> args = absl::ParseCommandLine(argc, argv); + + // Print RTC_LOG warnings and errors even in release builds. + if (rtc::LogMessage::GetLogToDebug() > rtc::LS_WARNING) { + rtc::LogMessage::LogToDebug(rtc::LS_WARNING); + } + rtc::LogMessage::SetLogToStderr(true); + + webrtc::ParsedRtcEventLog::UnconfiguredHeaderExtensions header_extensions = + webrtc::ParsedRtcEventLog::UnconfiguredHeaderExtensions::kDontParse; + if (absl::GetFlag(FLAGS_parse_unconfigured_header_extensions)) { + header_extensions = webrtc::ParsedRtcEventLog:: + UnconfiguredHeaderExtensions::kAttemptWebrtcDefaultConfig; + } + + std::string inputfile; + FILE* output = nullptr; + if (args.size() == 3) { + inputfile = args[1]; + std::string outputfile = args[2]; + output = fopen(outputfile.c_str(), "w"); + } else if (args.size() == 2) { + inputfile = args[1]; + output = stdout; + } else { + // Print usage information. + std::cerr << absl::ProgramUsageMessage(); + return 1; + } + + bool success = webrtc::Convert(inputfile, output, header_extensions); + + return success ? 0 : 1; +} |