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());
|
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
|
} // namespace webrtc
|
||||||
|
|||||||
@ -35,6 +35,21 @@ class ParsedRtcEventLog {
|
|||||||
friend class RtcEventLogTestHelper;
|
friend class RtcEventLogTestHelper;
|
||||||
|
|
||||||
public:
|
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 {
|
enum EventType {
|
||||||
UNKNOWN_EVENT = 0,
|
UNKNOWN_EVENT = 0,
|
||||||
LOG_START = 1,
|
LOG_START = 1,
|
||||||
@ -142,6 +157,11 @@ class ParsedRtcEventLog {
|
|||||||
size_t index,
|
size_t index,
|
||||||
AudioNetworkAdaptor::EncoderRuntimeConfig* config) const;
|
AudioNetworkAdaptor::EncoderRuntimeConfig* config) const;
|
||||||
|
|
||||||
|
ParsedRtcEventLog::BweProbeClusterCreatedEvent GetBweProbeClusterCreated(
|
||||||
|
size_t index) const;
|
||||||
|
|
||||||
|
ParsedRtcEventLog::BweProbeResultEvent GetBweProbeResult(size_t index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<rtclog::Event> events_;
|
std::vector<rtclog::Event> events_;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -477,9 +477,12 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ParsedRtcEventLog::BWE_PROBE_CLUSTER_CREATED_EVENT: {
|
case ParsedRtcEventLog::BWE_PROBE_CLUSTER_CREATED_EVENT: {
|
||||||
|
bwe_probe_cluster_created_events_.push_back(
|
||||||
|
parsed_log_.GetBweProbeClusterCreated(i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT: {
|
case ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT: {
|
||||||
|
bwe_probe_result_events_.push_back(parsed_log_.GetBweProbeResult(i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ParsedRtcEventLog::UNKNOWN_EVENT: {
|
case ParsedRtcEventLog::UNKNOWN_EVENT: {
|
||||||
@ -938,7 +941,26 @@ void EventLogAnalyzer::CreateTotalBitrateGraph(
|
|||||||
float y = static_cast<float>(bwe_update.new_bitrate) / 1000;
|
float y = static_cast<float>(bwe_update.new_bitrate) / 1000;
|
||||||
time_series->points.emplace_back(x, y);
|
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->SetXAxis(0, call_duration_s_, "Time (s)", kLeftMargin, kRightMargin);
|
||||||
plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
|
plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);
|
||||||
if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
|
if (desired_direction == webrtc::PacketDirection::kIncomingPacket) {
|
||||||
|
|||||||
@ -167,6 +167,11 @@ class EventLogAnalyzer {
|
|||||||
|
|
||||||
std::vector<AudioNetworkAdaptationEvent> audio_network_adaptation_events_;
|
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.
|
// Window and step size used for calculating moving averages, e.g. bitrate.
|
||||||
// The generated data points will be |step_| microseconds apart.
|
// The generated data points will be |step_| microseconds apart.
|
||||||
// Only events occuring at most |window_duration_| microseconds before the
|
// Only events occuring at most |window_duration_| microseconds before the
|
||||||
|
|||||||
@ -10,6 +10,7 @@ message ChartStyle {
|
|||||||
LINE_CHART = 1;
|
LINE_CHART = 1;
|
||||||
BAR_CHART = 2;
|
BAR_CHART = 2;
|
||||||
LINE_STEP_CHART = 3;
|
LINE_STEP_CHART = 3;
|
||||||
|
SCATTER_CHART = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,13 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace plotting {
|
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 {
|
struct TimeSeriesPoint {
|
||||||
TimeSeriesPoint(float x, float y) : x(x), y(y) {}
|
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);
|
data_set->set_highlight_points(true);
|
||||||
} else if (series_list_[i].style == LINE_STEP_GRAPH) {
|
} else if (series_list_[i].style == LINE_STEP_GRAPH) {
|
||||||
data_set->set_style(webrtc::analytics::ChartStyle::LINE_STEP_CHART);
|
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 {
|
} else {
|
||||||
data_set->set_style(webrtc::analytics::ChartStyle::UNDEFINED);
|
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], "
|
"plt.plot(x%zu[1:], y%zu[:-1], color=rgb_colors[%zu], "
|
||||||
"label=\'%s\')\n",
|
"label=\'%s\')\n",
|
||||||
i, i, i, series_list_[i].label.c_str());
|
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 {
|
} else {
|
||||||
printf("raise Exception(\"Unknown graph type\")\n");
|
printf("raise Exception(\"Unknown graph type\")\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user