Visualize events related to probing in the total bitrate graph.
BUG=webrtc:6984 R=terelius@webrtc.org Review-Url: https://codereview.webrtc.org/2782553005 . Cr-Commit-Position: refs/heads/master@{#17449}
This commit is contained in:
@ -534,4 +534,58 @@ void ParsedRtcEventLog::GetAudioNetworkAdaptation(
|
||||
rtc::Optional<float>(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<uint64_t>(pr_event.bitrate_bps());
|
||||
} else if (pr_event.result() ==
|
||||
rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL) {
|
||||
res.failure_reason =
|
||||
rtc::Optional<ProbeFailureReason>(kInvalidSendReceiveInterval);
|
||||
} else if (pr_event.result() ==
|
||||
rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO) {
|
||||
res.failure_reason =
|
||||
rtc::Optional<ProbeFailureReason>(kInvalidSendReceiveRatio);
|
||||
} else if (pr_event.result() == rtclog::BweProbeResult::TIMEOUT) {
|
||||
res.failure_reason = rtc::Optional<ProbeFailureReason>(kTimeout);
|
||||
} else {
|
||||
RTC_NOTREACHED();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -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<uint64_t> bitrate_bps;
|
||||
rtc::Optional<ProbeFailureReason> 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<rtclog::Event> events_;
|
||||
};
|
||||
|
||||
@ -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<float>(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<float>(cluster.timestamp - begin_time_) / 1000000;
|
||||
float y = static_cast<float>(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<float>(result.timestamp - begin_time_) / 1000000;
|
||||
float y = static_cast<float>(*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) {
|
||||
|
||||
@ -167,6 +167,11 @@ class EventLogAnalyzer {
|
||||
|
||||
std::vector<AudioNetworkAdaptationEvent> audio_network_adaptation_events_;
|
||||
|
||||
std::vector<ParsedRtcEventLog::BweProbeClusterCreatedEvent>
|
||||
bwe_probe_cluster_created_events_;
|
||||
|
||||
std::vector<ParsedRtcEventLog::BweProbeResultEvent> 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
|
||||
|
||||
@ -10,6 +10,7 @@ message ChartStyle {
|
||||
LINE_CHART = 1;
|
||||
BAR_CHART = 2;
|
||||
LINE_STEP_CHART = 3;
|
||||
SCATTER_CHART = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) {}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user