diff --git a/webrtc/tools/event_log_visualizer/analyzer.cc b/webrtc/tools/event_log_visualizer/analyzer.cc index 7797825e2a..5a8733c074 100644 --- a/webrtc/tools/event_log_visualizer/analyzer.cc +++ b/webrtc/tools/event_log_visualizer/analyzer.cc @@ -459,18 +459,33 @@ class BitrateObserver : public CongestionController::Observer, bool bitrate_updated_; }; -bool EventLogAnalyzer::IsRtxSsrc(StreamId stream_id) { +bool EventLogAnalyzer::IsRtxSsrc(StreamId stream_id) const { return rtx_ssrcs_.count(stream_id) == 1; } -bool EventLogAnalyzer::IsVideoSsrc(StreamId stream_id) { +bool EventLogAnalyzer::IsVideoSsrc(StreamId stream_id) const { return video_ssrcs_.count(stream_id) == 1; } -bool EventLogAnalyzer::IsAudioSsrc(StreamId stream_id) { +bool EventLogAnalyzer::IsAudioSsrc(StreamId stream_id) const { return audio_ssrcs_.count(stream_id) == 1; } +std::string EventLogAnalyzer::GetStreamName(StreamId stream_id) const { + std::stringstream name; + if (IsAudioSsrc(stream_id)) { + name << "Audio "; + } else if (IsVideoSsrc(stream_id)) { + name << "Video "; + } else { + name << "Unknown "; + } + if (IsRtxSsrc(stream_id)) + name << "RTX "; + name << SsrcToString(stream_id.GetSsrc()); + return name.str(); +} + void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction, Plot* plot) { for (auto& kv : rtp_packets_) { @@ -483,7 +498,7 @@ void EventLogAnalyzer::CreatePacketGraph(PacketDirection desired_direction, } TimeSeries time_series; - time_series.label = SsrcToString(stream_id.GetSsrc()); + time_series.label = GetStreamName(stream_id); time_series.style = BAR_GRAPH; Pointwise(packet_stream, begin_time_, &time_series); plot->series_list_.push_back(std::move(time_series)); @@ -515,7 +530,7 @@ void EventLogAnalyzer::CreateAccumulatedPacketsTimeSeries( } TimeSeries time_series; - time_series.label = label_prefix + " " + SsrcToString(stream_id.GetSsrc()); + time_series.label = label_prefix + " " + GetStreamName(stream_id); time_series.style = LINE_GRAPH; for (size_t i = 0; i < packet_stream.size(); i++) { @@ -597,7 +612,7 @@ void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) { } TimeSeries time_series; - time_series.label = SsrcToString(stream_id.GetSsrc()); + time_series.label = GetStreamName(stream_id); time_series.style = BAR_GRAPH; Pairwise(packet_stream, begin_time_, &time_series); plot->series_list_.push_back(std::move(time_series)); @@ -609,27 +624,72 @@ void EventLogAnalyzer::CreateSequenceNumberGraph(Plot* plot) { plot->SetTitle("Sequence number"); } +void EventLogAnalyzer::CreateIncomingPacketLossGraph(Plot* plot) { + for (auto& kv : rtp_packets_) { + StreamId stream_id = kv.first; + const std::vector& packet_stream = kv.second; + // Filter on direction and SSRC. + if (stream_id.GetDirection() != kIncomingPacket || + !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_)) { + continue; + } + + TimeSeries time_series; + time_series.label = GetStreamName(stream_id); + time_series.style = LINE_DOT_GRAPH; + const uint64_t kWindowUs = 1000000; + const LoggedRtpPacket* first_in_window = &packet_stream.front(); + const LoggedRtpPacket* last_in_window = &packet_stream.front(); + int packets_in_window = 0; + for (const LoggedRtpPacket& packet : packet_stream) { + if (packet.timestamp > first_in_window->timestamp + kWindowUs) { + uint16_t expected_num_packets = last_in_window->header.sequenceNumber - + first_in_window->header.sequenceNumber + 1; + float fraction_lost = (expected_num_packets - packets_in_window) / + static_cast(expected_num_packets); + float y = fraction_lost * 100; + float x = + static_cast(last_in_window->timestamp - begin_time_) / + 1000000; + time_series.points.emplace_back(x, y); + first_in_window = &packet; + last_in_window = &packet; + packets_in_window = 1; + continue; + } + ++packets_in_window; + last_in_window = &packet; + } + plot->series_list_.push_back(std::move(time_series)); + } + + plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); + plot->SetSuggestedYAxis(0, 1, "Estimated loss rate (%)", kBottomMargin, + kTopMargin); + plot->SetTitle("Estimated incoming loss rate"); +} + void EventLogAnalyzer::CreateDelayChangeGraph(Plot* plot) { for (auto& kv : rtp_packets_) { StreamId stream_id = kv.first; const std::vector& packet_stream = kv.second; - uint32_t ssrc = stream_id.GetSsrc(); // Filter on direction and SSRC. if (stream_id.GetDirection() != kIncomingPacket || - !MatchingSsrc(ssrc, desired_ssrc_) || IsAudioSsrc(stream_id) || - !IsVideoSsrc(stream_id) || IsRtxSsrc(stream_id)) { + !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_) || + IsAudioSsrc(stream_id) || !IsVideoSsrc(stream_id) || + IsRtxSsrc(stream_id)) { continue; } TimeSeries capture_time_data; - capture_time_data.label = SsrcToString(ssrc) + " capture-time"; + capture_time_data.label = GetStreamName(stream_id) + " capture-time"; capture_time_data.style = BAR_GRAPH; Pairwise(packet_stream, begin_time_, &capture_time_data); plot->series_list_.push_back(std::move(capture_time_data)); TimeSeries send_time_data; - send_time_data.label = SsrcToString(ssrc) + " abs-send-time"; + send_time_data.label = GetStreamName(stream_id) + " abs-send-time"; send_time_data.style = BAR_GRAPH; Pairwise(packet_stream, begin_time_, &send_time_data); @@ -646,23 +706,23 @@ void EventLogAnalyzer::CreateAccumulatedDelayChangeGraph(Plot* plot) { for (auto& kv : rtp_packets_) { StreamId stream_id = kv.first; const std::vector& packet_stream = kv.second; - uint32_t ssrc = stream_id.GetSsrc(); // Filter on direction and SSRC. if (stream_id.GetDirection() != kIncomingPacket || - !MatchingSsrc(ssrc, desired_ssrc_) || IsAudioSsrc(stream_id) || - !IsVideoSsrc(stream_id) || IsRtxSsrc(stream_id)) { + !MatchingSsrc(stream_id.GetSsrc(), desired_ssrc_) || + IsAudioSsrc(stream_id) || !IsVideoSsrc(stream_id) || + IsRtxSsrc(stream_id)) { continue; } TimeSeries capture_time_data; - capture_time_data.label = SsrcToString(ssrc) + " capture-time"; + capture_time_data.label = GetStreamName(stream_id) + " capture-time"; capture_time_data.style = LINE_GRAPH; Pairwise>( packet_stream, begin_time_, &capture_time_data); plot->series_list_.push_back(std::move(capture_time_data)); TimeSeries send_time_data; - send_time_data.label = SsrcToString(ssrc) + " abs-send-time"; + send_time_data.label = GetStreamName(stream_id) + " abs-send-time"; send_time_data.style = LINE_GRAPH; Pairwise>( packet_stream, begin_time_, &send_time_data); @@ -788,7 +848,7 @@ void EventLogAnalyzer::CreateStreamBitrateGraph( } TimeSeries time_series; - time_series.label = SsrcToString(stream_id.GetSsrc()); + time_series.label = GetStreamName(stream_id); time_series.style = LINE_GRAPH; double bytes_to_kilobits = 8.0 / 1000; MovingAverage(packet_stream, begin_time_, end_time_, diff --git a/webrtc/tools/event_log_visualizer/analyzer.h b/webrtc/tools/event_log_visualizer/analyzer.h index 74c0ff0875..402f75f904 100644 --- a/webrtc/tools/event_log_visualizer/analyzer.h +++ b/webrtc/tools/event_log_visualizer/analyzer.h @@ -68,6 +68,8 @@ class EventLogAnalyzer { void CreateSequenceNumberGraph(Plot* plot); + void CreateIncomingPacketLossGraph(Plot* plot); + void CreateDelayChangeGraph(Plot* plot); void CreateAccumulatedDelayChangeGraph(Plot* plot); @@ -110,11 +112,13 @@ class EventLogAnalyzer { const std::map>& packets, const std::string& label_prefix); - bool IsRtxSsrc(StreamId stream_id); + bool IsRtxSsrc(StreamId stream_id) const; - bool IsVideoSsrc(StreamId stream_id); + bool IsVideoSsrc(StreamId stream_id) const; - bool IsAudioSsrc(StreamId stream_id); + bool IsAudioSsrc(StreamId stream_id) const; + + std::string GetStreamName(StreamId) const; const ParsedRtcEventLog& parsed_log_; diff --git a/webrtc/tools/event_log_visualizer/main.cc b/webrtc/tools/event_log_visualizer/main.cc index a56947c484..a3e931a281 100644 --- a/webrtc/tools/event_log_visualizer/main.cc +++ b/webrtc/tools/event_log_visualizer/main.cc @@ -128,6 +128,7 @@ int main(int argc, char* argv[]) { if (FLAGS_plot_all || FLAGS_plot_fraction_loss) { analyzer.CreateFractionLossGraph(collection->AppendNewPlot()); + analyzer.CreateIncomingPacketLossGraph(collection->AppendNewPlot()); } if (FLAGS_plot_all || FLAGS_plot_total_bitrate) {