From b1222c203efca071a4095d3ec16168713e881f31 Mon Sep 17 00:00:00 2001 From: Bjorn Terelius Date: Tue, 24 Jul 2018 13:45:31 +0200 Subject: [PATCH] Plot RTCP SR and RR contents in event_log_visualizer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plot the contents of all report blocks in all sender and receiver reports. This includes fraction lost, cumulative number of lost packets, extended highest sequence number and time since last received SR. Bug: None Change-Id: Ifbded689a666da140c468e11c33b6c6f99a3041e Reviewed-on: https://webrtc-review.googlesource.com/90247 Reviewed-by: Alex Narest Commit-Queue: Björn Terelius Cr-Commit-Position: refs/heads/master@{#24083} --- rtc_tools/event_log_visualizer/analyzer.cc | 55 ++++++++++++++++++++ rtc_tools/event_log_visualizer/analyzer.h | 6 +++ rtc_tools/event_log_visualizer/main.cc | 60 ++++++++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/rtc_tools/event_log_visualizer/analyzer.cc b/rtc_tools/event_log_visualizer/analyzer.cc index 75558450ae..4ddd68c9e4 100644 --- a/rtc_tools/event_log_visualizer/analyzer.cc +++ b/rtc_tools/event_log_visualizer/analyzer.cc @@ -1458,6 +1458,61 @@ void EventLogAnalyzer::CreateTimestampGraph(PacketDirection direction, plot->SetTitle(GetDirectionAsString(direction) + " timestamps"); } +void EventLogAnalyzer::CreateSenderAndReceiverReportPlot( + PacketDirection direction, + rtc::FunctionView fy, + std::string title, + std::string yaxis_label, + Plot* plot) { + std::map sr_reports_by_ssrc; + const auto& sender_reports = parsed_log_.sender_reports(direction); + for (const auto& rtcp : sender_reports) { + float x = ToCallTimeSec(rtcp.log_time_us()); + uint32_t ssrc = rtcp.sr.sender_ssrc(); + for (const auto& block : rtcp.sr.report_blocks()) { + float y = fy(block); + auto sr_report_it = sr_reports_by_ssrc.find(ssrc); + bool inserted; + if (sr_report_it == sr_reports_by_ssrc.end()) { + std::tie(sr_report_it, inserted) = sr_reports_by_ssrc.emplace( + ssrc, TimeSeries(GetStreamName(direction, ssrc) + " Sender Reports", + LineStyle::kLine, PointStyle::kHighlight)); + } + sr_report_it->second.points.emplace_back(x, y); + } + } + for (auto& kv : sr_reports_by_ssrc) { + plot->AppendTimeSeries(std::move(kv.second)); + } + + std::map rr_reports_by_ssrc; + const auto& receiver_reports = parsed_log_.receiver_reports(direction); + for (const auto& rtcp : receiver_reports) { + float x = ToCallTimeSec(rtcp.log_time_us()); + uint32_t ssrc = rtcp.rr.sender_ssrc(); + for (const auto& block : rtcp.rr.report_blocks()) { + float y = fy(block); + auto rr_report_it = rr_reports_by_ssrc.find(ssrc); + bool inserted; + if (rr_report_it == rr_reports_by_ssrc.end()) { + std::tie(rr_report_it, inserted) = rr_reports_by_ssrc.emplace( + ssrc, + TimeSeries(GetStreamName(direction, ssrc) + " Receiver Reports", + LineStyle::kLine, PointStyle::kHighlight)); + } + rr_report_it->second.points.emplace_back(x, y); + } + } + for (auto& kv : rr_reports_by_ssrc) { + plot->AppendTimeSeries(std::move(kv.second)); + } + + plot->SetXAxis(ToCallTimeSec(begin_time_), call_duration_s_, "Time (s)", + kLeftMargin, kRightMargin); + plot->SetSuggestedYAxis(0, 1, yaxis_label, kBottomMargin, kTopMargin); + plot->SetTitle(title); +} + void EventLogAnalyzer::CreateAudioEncoderTargetBitrateGraph(Plot* plot) { TimeSeries time_series("Audio encoder target bitrate", LineStyle::kLine, PointStyle::kHighlight); diff --git a/rtc_tools/event_log_visualizer/analyzer.h b/rtc_tools/event_log_visualizer/analyzer.h index 22101b6585..4b8c27c951 100644 --- a/rtc_tools/event_log_visualizer/analyzer.h +++ b/rtc_tools/event_log_visualizer/analyzer.h @@ -64,6 +64,12 @@ class EventLogAnalyzer { void CreatePacerDelayGraph(Plot* plot); void CreateTimestampGraph(PacketDirection direction, Plot* plot); + void CreateSenderAndReceiverReportPlot( + PacketDirection direction, + rtc::FunctionView fy, + std::string title, + std::string yaxis_label, + Plot* plot); void CreateAudioEncoderTargetBitrateGraph(Plot* plot); void CreateAudioEncoderFrameLengthGraph(Plot* plot); diff --git a/rtc_tools/event_log_visualizer/main.cc b/rtc_tools/event_log_visualizer/main.cc index b1fc0d2847..fb497db577 100644 --- a/rtc_tools/event_log_visualizer/main.cc +++ b/rtc_tools/event_log_visualizer/main.cc @@ -97,6 +97,12 @@ DEFINE_bool(plot_pacer_delay, DEFINE_bool(plot_timestamps, false, "Plot the rtp timestamps of all rtp and rtcp packets over time."); +DEFINE_bool(plot_rtcp_details, + false, + "Plot the contents of all report blocks in all sender and receiver " + "reports. This includes fraction lost, cumulative number of lost " + "packets, extended highest sequence number and time since last " + "received SR."); DEFINE_bool(plot_audio_encoder_bitrate_bps, false, "Plot the audio encoder target bitrate."); @@ -305,6 +311,59 @@ int main(int argc, char* argv[]) { analyzer.CreateTimestampGraph(webrtc::kOutgoingPacket, collection->AppendNewPlot()); } + if (FLAG_plot_rtcp_details) { + auto GetFractionLost = [](const webrtc::rtcp::ReportBlock& block) -> float { + return static_cast(block.fraction_lost()) / 256 * 100; + }; + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kIncomingPacket, GetFractionLost, + "Fraction lost (incoming RTCP)", "Loss rate (percent)", + collection->AppendNewPlot()); + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kOutgoingPacket, GetFractionLost, + "Fraction lost (outgoing RTCP)", "Loss rate (percent)", + collection->AppendNewPlot()); + + auto GetCumulativeLost = + [](const webrtc::rtcp::ReportBlock& block) -> float { + return block.cumulative_lost_signed(); + }; + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kIncomingPacket, GetCumulativeLost, + "Cumulative lost packets (incoming RTCP)", "Packets", + collection->AppendNewPlot()); + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kOutgoingPacket, GetCumulativeLost, + "Cumulative lost packets (outgoing RTCP)", "Packets", + collection->AppendNewPlot()); + + auto GetHighestSeqNumber = + [](const webrtc::rtcp::ReportBlock& block) -> float { + return block.extended_high_seq_num(); + }; + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kIncomingPacket, GetHighestSeqNumber, + "Highest sequence number (incoming RTCP)", "Seqence number", + collection->AppendNewPlot()); + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kOutgoingPacket, GetHighestSeqNumber, + "Highest sequence number (outgoing RTCP)", "Seqence number", + collection->AppendNewPlot()); + + auto DelaySinceLastSr = + [](const webrtc::rtcp::ReportBlock& block) -> float { + return static_cast(block.delay_since_last_sr()) / 65536; + }; + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kIncomingPacket, DelaySinceLastSr, + "Delay since last received sender report (incoming RTCP)", "Time (s)", + collection->AppendNewPlot()); + analyzer.CreateSenderAndReceiverReportPlot( + webrtc::kOutgoingPacket, DelaySinceLastSr, + "Delay since last received sender report (outgoing RTCP)", "Time (s)", + collection->AppendNewPlot()); + } + if (FLAG_plot_pacer_delay) { analyzer.CreatePacerDelayGraph(collection->AppendNewPlot()); } @@ -410,6 +469,7 @@ void SetAllPlotFlags(bool setting) { FLAG_plot_network_delay_feedback = setting; FLAG_plot_fraction_loss_feedback = setting; FLAG_plot_timestamps = setting; + FLAG_plot_rtcp_details = setting; FLAG_plot_audio_encoder_bitrate_bps = setting; FLAG_plot_audio_encoder_frame_length_ms = setting; FLAG_plot_audio_encoder_packet_loss = setting;