diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc b/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc index a806b3db0e..815308df11 100644 --- a/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc @@ -534,4 +534,58 @@ void ParsedRtcEventLog::GetAudioNetworkAdaptation( rtc::Optional(ana_event.uplink_packet_loss_fraction()); } +ParsedRtcEventLog::BweProbeClusterCreatedEvent +ParsedRtcEventLog::GetBweProbeClusterCreated(size_t index) const { + RTC_CHECK_LT(index, GetNumberOfEvents()); + const rtclog::Event& event = events_[index]; + RTC_CHECK(event.has_type()); + RTC_CHECK_EQ(event.type(), rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT); + RTC_CHECK(event.has_probe_cluster()); + const rtclog::BweProbeCluster& pcc_event = event.probe_cluster(); + BweProbeClusterCreatedEvent res; + res.timestamp = GetTimestamp(index); + RTC_CHECK(pcc_event.has_id()); + res.id = pcc_event.id(); + RTC_CHECK(pcc_event.has_bitrate_bps()); + res.bitrate_bps = pcc_event.bitrate_bps(); + RTC_CHECK(pcc_event.has_min_packets()); + res.min_packets = pcc_event.min_packets(); + RTC_CHECK(pcc_event.has_min_bytes()); + res.min_bytes = pcc_event.min_bytes(); + return res; +} + +ParsedRtcEventLog::BweProbeResultEvent ParsedRtcEventLog::GetBweProbeResult( + size_t index) const { + RTC_CHECK_LT(index, GetNumberOfEvents()); + const rtclog::Event& event = events_[index]; + RTC_CHECK(event.has_type()); + RTC_CHECK_EQ(event.type(), rtclog::Event::BWE_PROBE_RESULT_EVENT); + RTC_CHECK(event.has_probe_result()); + const rtclog::BweProbeResult& pr_event = event.probe_result(); + BweProbeResultEvent res; + res.timestamp = GetTimestamp(index); + RTC_CHECK(pr_event.has_id()); + res.id = pr_event.id(); + + RTC_CHECK(pr_event.has_result()); + if (pr_event.result() == rtclog::BweProbeResult::SUCCESS) { + RTC_CHECK(pr_event.has_bitrate_bps()); + res.bitrate_bps = rtc::Optional(pr_event.bitrate_bps()); + } else if (pr_event.result() == + rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL) { + res.failure_reason = + rtc::Optional(kInvalidSendReceiveInterval); + } else if (pr_event.result() == + rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO) { + res.failure_reason = + rtc::Optional(kInvalidSendReceiveRatio); + } else if (pr_event.result() == rtclog::BweProbeResult::TIMEOUT) { + res.failure_reason = rtc::Optional(kTimeout); + } else { + RTC_NOTREACHED(); + } + + return res; +} } // namespace webrtc diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_parser.h b/webrtc/logging/rtc_event_log/rtc_event_log_parser.h index 1460a4ca83..bb3c406d65 100644 --- a/webrtc/logging/rtc_event_log/rtc_event_log_parser.h +++ b/webrtc/logging/rtc_event_log/rtc_event_log_parser.h @@ -35,6 +35,21 @@ class ParsedRtcEventLog { friend class RtcEventLogTestHelper; public: + struct BweProbeClusterCreatedEvent { + uint64_t timestamp; + uint32_t id; + uint64_t bitrate_bps; + uint32_t min_packets; + uint32_t min_bytes; + }; + + struct BweProbeResultEvent { + uint64_t timestamp; + uint32_t id; + rtc::Optional bitrate_bps; + rtc::Optional failure_reason; + }; + enum EventType { UNKNOWN_EVENT = 0, LOG_START = 1, @@ -142,6 +157,11 @@ class ParsedRtcEventLog { size_t index, AudioNetworkAdaptor::EncoderRuntimeConfig* config) const; + ParsedRtcEventLog::BweProbeClusterCreatedEvent GetBweProbeClusterCreated( + size_t index) const; + + ParsedRtcEventLog::BweProbeResultEvent GetBweProbeResult(size_t index) const; + private: std::vector events_; }; diff --git a/webrtc/tools/event_log_visualizer/analyzer.cc b/webrtc/tools/event_log_visualizer/analyzer.cc index c986ff7db9..ba95c2565d 100644 --- a/webrtc/tools/event_log_visualizer/analyzer.cc +++ b/webrtc/tools/event_log_visualizer/analyzer.cc @@ -477,9 +477,12 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log) break; } case ParsedRtcEventLog::BWE_PROBE_CLUSTER_CREATED_EVENT: { + bwe_probe_cluster_created_events_.push_back( + parsed_log_.GetBweProbeClusterCreated(i)); break; } case ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT: { + bwe_probe_result_events_.push_back(parsed_log_.GetBweProbeResult(i)); break; } case ParsedRtcEventLog::UNKNOWN_EVENT: { @@ -938,7 +941,26 @@ void EventLogAnalyzer::CreateTotalBitrateGraph( float y = static_cast(bwe_update.new_bitrate) / 1000; time_series->points.emplace_back(x, y); } + + TimeSeries* created_series = + plot->AddTimeSeries("Probe cluster created.", DOT_GRAPH); + for (auto& cluster : bwe_probe_cluster_created_events_) { + float x = static_cast(cluster.timestamp - begin_time_) / 1000000; + float y = static_cast(cluster.bitrate_bps) / 1000; + created_series->points.emplace_back(x, y); + } + + TimeSeries* result_series = + plot->AddTimeSeries("Probing results.", DOT_GRAPH); + for (auto& result : bwe_probe_result_events_) { + if (result.bitrate_bps) { + float x = static_cast(result.timestamp - begin_time_) / 1000000; + float y = static_cast(*result.bitrate_bps) / 1000; + result_series->points.emplace_back(x, y); + } + } } + plot->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin); plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin); if (desired_direction == webrtc::PacketDirection::kIncomingPacket) { diff --git a/webrtc/tools/event_log_visualizer/analyzer.h b/webrtc/tools/event_log_visualizer/analyzer.h index 9773f2fc41..1acf756133 100644 --- a/webrtc/tools/event_log_visualizer/analyzer.h +++ b/webrtc/tools/event_log_visualizer/analyzer.h @@ -167,6 +167,11 @@ class EventLogAnalyzer { std::vector audio_network_adaptation_events_; + std::vector + bwe_probe_cluster_created_events_; + + std::vector bwe_probe_result_events_; + // Window and step size used for calculating moving averages, e.g. bitrate. // The generated data points will be |step_| microseconds apart. // Only events occuring at most |window_duration_| microseconds before the diff --git a/webrtc/tools/event_log_visualizer/chart.proto b/webrtc/tools/event_log_visualizer/chart.proto index e005391c9f..41e3ebd330 100644 --- a/webrtc/tools/event_log_visualizer/chart.proto +++ b/webrtc/tools/event_log_visualizer/chart.proto @@ -10,6 +10,7 @@ message ChartStyle { LINE_CHART = 1; BAR_CHART = 2; LINE_STEP_CHART = 3; + SCATTER_CHART = 4; } } diff --git a/webrtc/tools/event_log_visualizer/plot_base.h b/webrtc/tools/event_log_visualizer/plot_base.h index 0c0ebc0b7c..b2ab299a58 100644 --- a/webrtc/tools/event_log_visualizer/plot_base.h +++ b/webrtc/tools/event_log_visualizer/plot_base.h @@ -18,7 +18,13 @@ namespace webrtc { namespace plotting { -enum PlotStyle { LINE_GRAPH, LINE_DOT_GRAPH, BAR_GRAPH, LINE_STEP_GRAPH }; +enum PlotStyle { + LINE_GRAPH, + LINE_DOT_GRAPH, + BAR_GRAPH, + LINE_STEP_GRAPH, + DOT_GRAPH +}; struct TimeSeriesPoint { TimeSeriesPoint(float x, float y) : x(x), y(y) {} diff --git a/webrtc/tools/event_log_visualizer/plot_protobuf.cc b/webrtc/tools/event_log_visualizer/plot_protobuf.cc index 6e4558579b..d5e9192351 100644 --- a/webrtc/tools/event_log_visualizer/plot_protobuf.cc +++ b/webrtc/tools/event_log_visualizer/plot_protobuf.cc @@ -40,6 +40,9 @@ void ProtobufPlot::ExportProtobuf(webrtc::analytics::Chart* chart) { data_set->set_highlight_points(true); } else if (series_list_[i].style == LINE_STEP_GRAPH) { data_set->set_style(webrtc::analytics::ChartStyle::LINE_STEP_CHART); + } else if (series_list_[i].style == DOT_GRAPH) { + data_set->set_style(webrtc::analytics::ChartStyle::SCATTER_CHART); + data_set->set_highlight_points(true); } else { data_set->set_style(webrtc::analytics::ChartStyle::UNDEFINED); } diff --git a/webrtc/tools/event_log_visualizer/plot_python.cc b/webrtc/tools/event_log_visualizer/plot_python.cc index c91efe32c7..863c05f990 100644 --- a/webrtc/tools/event_log_visualizer/plot_python.cc +++ b/webrtc/tools/event_log_visualizer/plot_python.cc @@ -75,6 +75,11 @@ void PythonPlot::Draw() { "plt.plot(x%zu[1:], y%zu[:-1], color=rgb_colors[%zu], " "label=\'%s\')\n", i, i, i, series_list_[i].label.c_str()); + } else if (series_list_[i].style == DOT_GRAPH) { + printf( + "plt.plot(x%zu, y%zu, color=rgb_colors[%zu], label=\'%s\', " + "marker='.', ls=' ')\n", + i, i, i, series_list_[i].label.c_str()); } else { printf("raise Exception(\"Unknown graph type\")\n"); }