diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer.cc b/rtc_tools/rtc_event_log_visualizer/analyzer.cc index b8399f9529..cc51c79fd2 100644 --- a/rtc_tools/rtc_event_log_visualizer/analyzer.cc +++ b/rtc_tools/rtc_event_log_visualizer/analyzer.cc @@ -449,6 +449,23 @@ float DelaySinceLastSr(const webrtc::rtcp::ReportBlock& block) { return static_cast(block.delay_since_last_sr()) / 65536; } +std::map BuildCandidateIdLogDescriptionMap( + const std::vector& + ice_candidate_pair_configs) { + std::map candidate_pair_desc_by_id; + for (const auto& config : ice_candidate_pair_configs) { + // TODO(qingsi): Add the handling of the "Updated" config event after the + // visualization of property change for candidate pairs is introduced. + if (candidate_pair_desc_by_id.find(config.candidate_pair_id) == + candidate_pair_desc_by_id.end()) { + const std::string candidate_pair_desc = + GetCandidatePairLogDescriptionAsString(config); + candidate_pair_desc_by_id[config.candidate_pair_id] = candidate_pair_desc; + } + } + return candidate_pair_desc_by_id; +} + } // namespace EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log, @@ -697,7 +714,7 @@ void EventLogAnalyzer::InitializeMapOfNamedGraphs(bool show_detector_state, } void EventLogAnalyzer::CreateGraphsByName(const std::vector& names, - PlotCollection* collection) { + PlotCollection* collection) const { for (absl::string_view name : names) { auto plot = absl::c_find_if(plots_, [name](const PlotDeclaration& plot) { return plot.label == name; @@ -710,7 +727,7 @@ void EventLogAnalyzer::CreateGraphsByName(const std::vector& names, } void EventLogAnalyzer::CreatePacketGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) { // Filter on SSRC. if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) { @@ -738,7 +755,7 @@ void EventLogAnalyzer::CreatePacketGraph(PacketDirection direction, } void EventLogAnalyzer::CreateRtcpTypeGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { plot->AppendTimeSeries(CreateRtcpTypeTimeSeries( parsed_log_.transport_feedbacks(direction), config_, "TWCC", 1)); plot->AppendTimeSeries(CreateRtcpTypeTimeSeries( @@ -776,7 +793,7 @@ template void EventLogAnalyzer::CreateAccumulatedPacketsTimeSeries( Plot* plot, const IterableType& packets, - const std::string& label) { + const std::string& label) const { TimeSeries time_series(label, LineStyle::kStep); for (size_t i = 0; i < packets.size(); i++) { float x = config_.GetCallTimeSec(packets[i].log_time()); @@ -786,7 +803,7 @@ void EventLogAnalyzer::CreateAccumulatedPacketsTimeSeries( } void EventLogAnalyzer::CreateAccumulatedPacketsGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) { if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) continue; @@ -812,7 +829,7 @@ void EventLogAnalyzer::CreateAccumulatedPacketsGraph(PacketDirection direction, } void EventLogAnalyzer::CreatePacketRateGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { auto CountPackets = [](auto packet) { return 1.0; }; for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) { // Filter on SSRC. @@ -850,7 +867,7 @@ void EventLogAnalyzer::CreatePacketRateGraph(PacketDirection direction, } void EventLogAnalyzer::CreateTotalPacketRateGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { // Contains a log timestamp to enable counting logged events of different // types using MovingAverage(). class LogTime { @@ -901,7 +918,7 @@ void EventLogAnalyzer::CreateTotalPacketRateGraph(PacketDirection direction, } // For each SSRC, plot the time between the consecutive playouts. -void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) { +void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) const { for (const auto& playout_stream : parsed_log_.audio_playout_events()) { uint32_t ssrc = playout_stream.first; if (!MatchingSsrc(ssrc, desired_ssrc_)) @@ -926,7 +943,7 @@ void EventLogAnalyzer::CreatePlayoutGraph(Plot* plot) { plot->SetTitle("Audio playout"); } -void EventLogAnalyzer::CreateNetEqSetMinimumDelay(Plot* plot) { +void EventLogAnalyzer::CreateNetEqSetMinimumDelay(Plot* plot) const { for (const auto& playout_stream : parsed_log_.neteq_set_minimum_delay_events()) { uint32_t ssrc = playout_stream.first; @@ -952,7 +969,7 @@ void EventLogAnalyzer::CreateNetEqSetMinimumDelay(Plot* plot) { // For audio SSRCs, plot the audio level. void EventLogAnalyzer::CreateAudioLevelGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) { if (!IsAudioSsrc(parsed_log_, direction, stream.ssrc)) continue; @@ -979,7 +996,7 @@ void EventLogAnalyzer::CreateAudioLevelGraph(PacketDirection direction, // For each SSRC, plot the sequence number difference between consecutive // incoming packets. -void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) { +void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) const { for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) { // Filter on SSRC. if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) { @@ -1012,7 +1029,7 @@ void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) { plot->SetTitle("Incoming sequence number delta"); } -void EventLogAnalyzer::CreateIncomingPacketLossGraph(Plot* plot) { +void EventLogAnalyzer::CreateIncomingPacketLossGraph(Plot* plot) const { for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) { const std::vector& packets = stream.incoming_packets; @@ -1072,7 +1089,7 @@ void EventLogAnalyzer::CreateIncomingPacketLossGraph(Plot* plot) { plot->SetTitle("Incoming packet loss (derived from incoming packets)"); } -void EventLogAnalyzer::CreateIncomingDelayGraph(Plot* plot) { +void EventLogAnalyzer::CreateIncomingDelayGraph(Plot* plot) const { for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) { // Filter on SSRC. if (!MatchingSsrc(stream.ssrc, desired_ssrc_) || @@ -1134,7 +1151,7 @@ void EventLogAnalyzer::CreateIncomingDelayGraph(Plot* plot) { } // Plot the fraction of packets lost (as perceived by the loss-based BWE). -void EventLogAnalyzer::CreateFractionLossGraph(Plot* plot) { +void EventLogAnalyzer::CreateFractionLossGraph(Plot* plot) const { TimeSeries time_series("Fraction lost", LineStyle::kLine, PointStyle::kHighlight); for (auto& bwe_update : parsed_log_.bwe_loss_updates()) { @@ -1151,7 +1168,7 @@ void EventLogAnalyzer::CreateFractionLossGraph(Plot* plot) { } // Plot the total bandwidth used by all RTP streams. -void EventLogAnalyzer::CreateTotalIncomingBitrateGraph(Plot* plot) { +void EventLogAnalyzer::CreateTotalIncomingBitrateGraph(Plot* plot) const { // TODO(terelius): This could be provided by the parser. std::multimap packets_in_order; for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) { @@ -1220,7 +1237,7 @@ void EventLogAnalyzer::CreateTotalOutgoingBitrateGraph( Plot* plot, bool show_detector_state, bool show_alr_state, - bool show_link_capacity) { + bool show_link_capacity) const { // TODO(terelius): This could be provided by the parser. std::multimap packets_in_order; for (const auto& stream : parsed_log_.outgoing_rtp_packets_by_ssrc()) { @@ -1435,7 +1452,7 @@ void EventLogAnalyzer::CreateTotalOutgoingBitrateGraph( // For each SSRC, plot the bandwidth used by that stream. void EventLogAnalyzer::CreateStreamBitrateGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) { // Filter on SSRC. if (!MatchingSsrc(stream.ssrc, desired_ssrc_)) { @@ -1462,7 +1479,7 @@ void EventLogAnalyzer::CreateStreamBitrateGraph(PacketDirection direction, // Computed from RTCP XR target bitrate block, so the graph is only populated if // those are sent. void EventLogAnalyzer::CreateBitrateAllocationGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { std::map time_series; const auto& xr_list = parsed_log_.extended_reports(direction); for (const auto& rtcp : xr_list) { @@ -1498,7 +1515,7 @@ void EventLogAnalyzer::CreateBitrateAllocationGraph(PacketDirection direction, plot->SetTitle("Target bitrate per outgoing layer"); } -void EventLogAnalyzer::CreateGoogCcSimulationGraph(Plot* plot) { +void EventLogAnalyzer::CreateGoogCcSimulationGraph(Plot* plot) const { TimeSeries target_rates("Simulated target rate", LineStyle::kStep, PointStyle::kHighlight); TimeSeries delay_based("Logged delay-based estimate", LineStyle::kStep, @@ -1540,7 +1557,7 @@ void EventLogAnalyzer::CreateGoogCcSimulationGraph(Plot* plot) { plot->SetTitle("Simulated BWE behavior"); } -void EventLogAnalyzer::CreateOutgoingTWCCLossRateGraph(Plot* plot) { +void EventLogAnalyzer::CreateOutgoingTWCCLossRateGraph(Plot* plot) const { TimeSeries loss_rate_series("Loss rate (from packet feedback)", LineStyle::kLine, PointStyle::kHighlight); TimeSeries reordered_packets_between_feedback( @@ -1662,7 +1679,7 @@ void EventLogAnalyzer::CreateOutgoingTWCCLossRateGraph(Plot* plot) { plot->SetTitle("Outgoing loss rate (from TWCC feedback)"); } -void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) { +void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) const { using RtpPacketType = LoggedRtpPacketOutgoing; using TransportFeedbackType = LoggedRtcpPacketTransportFeedback; @@ -1852,7 +1869,7 @@ void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) { plot->SetTitle("Simulated send-side BWE behavior"); } -void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) { +void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) const { using RtpPacketType = LoggedRtpPacketIncoming; class RembInterceptor { public: @@ -1935,7 +1952,7 @@ void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) { plot->SetTitle("Simulated receive-side BWE behavior"); } -void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) { +void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) const { TimeSeries time_series("Network delay", LineStyle::kLine, PointStyle::kHighlight); int64_t min_send_receive_diff_ms = std::numeric_limits::max(); @@ -1977,7 +1994,7 @@ void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) { plot->SetTitle("Outgoing network delay (based on per-packet feedback)"); } -void EventLogAnalyzer::CreatePacerDelayGraph(Plot* plot) { +void EventLogAnalyzer::CreatePacerDelayGraph(Plot* plot) const { for (const auto& stream : parsed_log_.outgoing_rtp_packets_by_ssrc()) { const std::vector& packets = stream.outgoing_packets; @@ -2036,7 +2053,7 @@ void EventLogAnalyzer::CreatePacerDelayGraph(Plot* plot) { } void EventLogAnalyzer::CreateTimestampGraph(PacketDirection direction, - Plot* plot) { + Plot* plot) const { for (const auto& stream : parsed_log_.rtp_packets_by_ssrc(direction)) { TimeSeries rtp_timestamps( GetStreamName(parsed_log_, direction, stream.ssrc) + " capture-time", @@ -2075,7 +2092,7 @@ void EventLogAnalyzer::CreateSenderAndReceiverReportPlot( rtc::FunctionView fy, std::string title, std::string yaxis_label, - Plot* plot) { + Plot* plot) const { std::map sr_reports_by_ssrc; const auto& sender_reports = parsed_log_.sender_reports(direction); for (const auto& rtcp : sender_reports) { @@ -2126,7 +2143,7 @@ void EventLogAnalyzer::CreateSenderAndReceiverReportPlot( plot->SetTitle(title); } -void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) { +void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) const { std::map configs_by_cp_id; for (const auto& config : parsed_log_.ice_candidate_pair_configs()) { if (configs_by_cp_id.find(config.candidate_pair_id) == @@ -2137,8 +2154,6 @@ void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) { TimeSeries("[" + std::to_string(config.candidate_pair_id) + "]" + candidate_pair_desc, LineStyle::kNone, PointStyle::kHighlight); - candidate_pair_desc_by_id_[config.candidate_pair_id] = - candidate_pair_desc; } float x = config_.GetCallTimeSec(config.log_time()); float y = static_cast(config.type); @@ -2165,37 +2180,20 @@ void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) { "SELECTED"}}); } -std::string EventLogAnalyzer::GetCandidatePairLogDescriptionFromId( - uint32_t candidate_pair_id) { - if (candidate_pair_desc_by_id_.find(candidate_pair_id) != - candidate_pair_desc_by_id_.end()) { - return candidate_pair_desc_by_id_[candidate_pair_id]; - } - for (const auto& config : parsed_log_.ice_candidate_pair_configs()) { - // TODO(qingsi): Add the handling of the "Updated" config event after the - // visualization of property change for candidate pairs is introduced. - if (candidate_pair_desc_by_id_.find(config.candidate_pair_id) == - candidate_pair_desc_by_id_.end()) { - const std::string candidate_pair_desc = - GetCandidatePairLogDescriptionAsString(config); - candidate_pair_desc_by_id_[config.candidate_pair_id] = - candidate_pair_desc; - } - } - return candidate_pair_desc_by_id_[candidate_pair_id]; -} - -void EventLogAnalyzer::CreateIceConnectivityCheckGraph(Plot* plot) { +void EventLogAnalyzer::CreateIceConnectivityCheckGraph(Plot* plot) const { constexpr int kEventTypeOffset = static_cast(IceCandidatePairConfigType::kNumValues); std::map checks_by_cp_id; + std::map candidate_pair_desc_by_id = + BuildCandidateIdLogDescriptionMap( + parsed_log_.ice_candidate_pair_configs()); for (const auto& event : parsed_log_.ice_candidate_pair_events()) { if (checks_by_cp_id.find(event.candidate_pair_id) == checks_by_cp_id.end()) { - checks_by_cp_id[event.candidate_pair_id] = TimeSeries( - "[" + std::to_string(event.candidate_pair_id) + "]" + - GetCandidatePairLogDescriptionFromId(event.candidate_pair_id), - LineStyle::kNone, PointStyle::kHighlight); + checks_by_cp_id[event.candidate_pair_id] = + TimeSeries("[" + std::to_string(event.candidate_pair_id) + "]" + + candidate_pair_desc_by_id[event.candidate_pair_id], + LineStyle::kNone, PointStyle::kHighlight); } float x = config_.GetCallTimeSec(event.log_time()); float y = static_cast(event.type) + kEventTypeOffset; @@ -2228,7 +2226,7 @@ void EventLogAnalyzer::CreateIceConnectivityCheckGraph(Plot* plot) { "RESPONSE RECEIVED"}}); } -void EventLogAnalyzer::CreateDtlsTransportStateGraph(Plot* plot) { +void EventLogAnalyzer::CreateDtlsTransportStateGraph(Plot* plot) const { TimeSeries states("DTLS Transport State", LineStyle::kNone, PointStyle::kHighlight); for (const auto& event : parsed_log_.dtls_transport_states()) { @@ -2250,7 +2248,7 @@ void EventLogAnalyzer::CreateDtlsTransportStateGraph(Plot* plot) { {static_cast(DtlsTransportState::kFailed), "FAILED"}}); } -void EventLogAnalyzer::CreateDtlsWritableStateGraph(Plot* plot) { +void EventLogAnalyzer::CreateDtlsWritableStateGraph(Plot* plot) const { TimeSeries writable("DTLS Writable", LineStyle::kNone, PointStyle::kHighlight); for (const auto& event : parsed_log_.dtls_writable_states()) { diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer.h b/rtc_tools/rtc_event_log_visualizer/analyzer.h index 25056738e2..c055a127fb 100644 --- a/rtc_tools/rtc_event_log_visualizer/analyzer.h +++ b/rtc_tools/rtc_event_log_visualizer/analyzer.h @@ -46,8 +46,12 @@ class EventLogAnalyzer { plots_.push_back({label, f}); } - std::vector::iterator begin() { return plots_.begin(); } - std::vector::iterator end() { return plots_.end(); } + std::vector::const_iterator begin() const { + return plots_.begin(); + } + std::vector::const_iterator end() const { + return plots_.end(); + } private: std::vector plots_; @@ -61,13 +65,13 @@ class EventLogAnalyzer { EventLogAnalyzer(const ParsedRtcEventLog& log, const AnalyzerConfig& config); void CreateGraphsByName(const std::vector& names, - PlotCollection* collection); + PlotCollection* collection) const; void InitializeMapOfNamedGraphs(bool show_detector_state, bool show_alr_state, bool show_link_capacity); - std::vector GetGraphNames() { + std::vector GetGraphNames() const { std::vector plot_names; for (const auto& plot : plots_) { plot_names.push_back(plot.label); @@ -75,71 +79,71 @@ class EventLogAnalyzer { return plot_names; } - void CreatePacketGraph(PacketDirection direction, Plot* plot); + void CreatePacketGraph(PacketDirection direction, Plot* plot) const; - void CreateRtcpTypeGraph(PacketDirection direction, Plot* plot); + void CreateRtcpTypeGraph(PacketDirection direction, Plot* plot) const; - void CreateAccumulatedPacketsGraph(PacketDirection direction, Plot* plot); + void CreateAccumulatedPacketsGraph(PacketDirection direction, + Plot* plot) const; - void CreatePacketRateGraph(PacketDirection direction, Plot* plot); + void CreatePacketRateGraph(PacketDirection direction, Plot* plot) const; - void CreateTotalPacketRateGraph(PacketDirection direction, Plot* plot); + void CreateTotalPacketRateGraph(PacketDirection direction, Plot* plot) const; - void CreatePlayoutGraph(Plot* plot); + void CreatePlayoutGraph(Plot* plot) const; - void CreateNetEqSetMinimumDelay(Plot* plot); + void CreateNetEqSetMinimumDelay(Plot* plot) const; - void CreateAudioLevelGraph(PacketDirection direction, Plot* plot); + void CreateAudioLevelGraph(PacketDirection direction, Plot* plot) const; - void CreateSequenceNumberGraph(Plot* plot); + void CreateSequenceNumberGraph(Plot* plot) const; - void CreateIncomingPacketLossGraph(Plot* plot); + void CreateIncomingPacketLossGraph(Plot* plot) const; - void CreateIncomingDelayGraph(Plot* plot); + void CreateIncomingDelayGraph(Plot* plot) const; - void CreateFractionLossGraph(Plot* plot); + void CreateFractionLossGraph(Plot* plot) const; - void CreateTotalIncomingBitrateGraph(Plot* plot); + void CreateTotalIncomingBitrateGraph(Plot* plot) const; void CreateTotalOutgoingBitrateGraph(Plot* plot, bool show_detector_state = false, bool show_alr_state = false, - bool show_link_capacity = false); + bool show_link_capacity = false) const; - void CreateStreamBitrateGraph(PacketDirection direction, Plot* plot); - void CreateBitrateAllocationGraph(PacketDirection direction, Plot* plot); + void CreateStreamBitrateGraph(PacketDirection direction, Plot* plot) const; + void CreateBitrateAllocationGraph(PacketDirection direction, + Plot* plot) const; - void CreateOutgoingTWCCLossRateGraph(Plot* plot); - void CreateGoogCcSimulationGraph(Plot* plot); - void CreateSendSideBweSimulationGraph(Plot* plot); - void CreateReceiveSideBweSimulationGraph(Plot* plot); + void CreateOutgoingTWCCLossRateGraph(Plot* plot) const; + void CreateGoogCcSimulationGraph(Plot* plot) const; + void CreateSendSideBweSimulationGraph(Plot* plot) const; + void CreateReceiveSideBweSimulationGraph(Plot* plot) const; - void CreateNetworkDelayFeedbackGraph(Plot* plot); - void CreatePacerDelayGraph(Plot* plot); + void CreateNetworkDelayFeedbackGraph(Plot* plot) const; + void CreatePacerDelayGraph(Plot* plot) const; - void CreateTimestampGraph(PacketDirection direction, Plot* plot); + void CreateTimestampGraph(PacketDirection direction, Plot* plot) const; void CreateSenderAndReceiverReportPlot( PacketDirection direction, rtc::FunctionView fy, std::string title, std::string yaxis_label, - Plot* plot); + Plot* plot) const; - void CreateIceCandidatePairConfigGraph(Plot* plot); - void CreateIceConnectivityCheckGraph(Plot* plot); + void CreateIceCandidatePairConfigGraph(Plot* plot) const; + void CreateIceConnectivityCheckGraph(Plot* plot) const; - void CreateDtlsTransportStateGraph(Plot* plot); - void CreateDtlsWritableStateGraph(Plot* plot); + void CreateDtlsTransportStateGraph(Plot* plot) const; + void CreateDtlsWritableStateGraph(Plot* plot) const; - void CreateTriageNotifications(); - void PrintNotifications(FILE* file); + void CreateTriageNotifications() const; + void PrintNotifications(FILE* file) const; private: template void CreateAccumulatedPacketsTimeSeries(Plot* plot, const IterableType& packets, - const std::string& label); - - std::string GetCandidatePairLogDescriptionFromId(uint32_t candidate_pair_id); + const std::string& label) const; const ParsedRtcEventLog& parsed_log_; @@ -147,8 +151,6 @@ class EventLogAnalyzer { // If left empty, all SSRCs will be considered relevant. std::vector desired_ssrc_; - std::map candidate_pair_desc_by_id_; - AnalyzerConfig config_; PlotMap plots_;