Add outgoing TWCC loss and missing packet feedback plots to event log analyzer.
Bug: webrtc:12707 Change-Id: I737177e6b6737c8c2e7d8803a68e29e9998ba9f8 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/321140 Reviewed-by: Björn Terelius <terelius@webrtc.org> Commit-Queue: Diep Bui <diepbp@webrtc.org> Cr-Commit-Position: refs/heads/main@{#40925}
This commit is contained in:
parent
ec48886da9
commit
636c3f24b8
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <deque>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -406,6 +407,12 @@ RtpPacketReceived RtpPacketForBWEFromHeader(const RTPHeader& header) {
|
|||||||
return rtp_packet;
|
return rtp_packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PacketLossSummary {
|
||||||
|
size_t num_packets = 0;
|
||||||
|
size_t num_lost_packets = 0;
|
||||||
|
Timestamp base_time = Timestamp::MinusInfinity();
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log,
|
EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log,
|
||||||
@ -1298,6 +1305,100 @@ void EventLogAnalyzer::CreateGoogCcSimulationGraph(Plot* plot) {
|
|||||||
plot->SetTitle("Simulated BWE behavior");
|
plot->SetTitle("Simulated BWE behavior");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventLogAnalyzer::CreateOutgoingTWCCLossRateGraph(Plot* plot) {
|
||||||
|
TimeSeries loss_rate_series("Loss rate (from packet feedback)",
|
||||||
|
LineStyle::kLine, PointStyle::kHighlight);
|
||||||
|
TimeSeries average_loss_rate_series("Average loss rate last 5s",
|
||||||
|
LineStyle::kLine, PointStyle::kHighlight);
|
||||||
|
TimeSeries missing_feedback_series("Missing feedback", LineStyle::kNone,
|
||||||
|
PointStyle::kHighlight);
|
||||||
|
PacketLossSummary window_summary;
|
||||||
|
Timestamp last_observation_receive_time = Timestamp::Zero();
|
||||||
|
|
||||||
|
// Use loss based bwe 2 observation duration and observation window size.
|
||||||
|
constexpr TimeDelta kObservationDuration = TimeDelta::Millis(250);
|
||||||
|
constexpr uint32_t kObservationWindowSize = 20;
|
||||||
|
std::deque<PacketLossSummary> observations;
|
||||||
|
SeqNumUnwrapper<uint16_t> unwrapper;
|
||||||
|
int64_t last_acked = 1;
|
||||||
|
if (!parsed_log_.transport_feedbacks(kIncomingPacket).empty()) {
|
||||||
|
last_acked =
|
||||||
|
unwrapper.Unwrap(parsed_log_.transport_feedbacks(kIncomingPacket)[0]
|
||||||
|
.transport_feedback.GetBaseSequence());
|
||||||
|
}
|
||||||
|
for (auto& feedback : parsed_log_.transport_feedbacks(kIncomingPacket)) {
|
||||||
|
const rtcp::TransportFeedback& transport_feedback =
|
||||||
|
feedback.transport_feedback;
|
||||||
|
size_t base_seq_num =
|
||||||
|
unwrapper.Unwrap(transport_feedback.GetBaseSequence());
|
||||||
|
// Collect packets that do not have feedback, which are from the last acked
|
||||||
|
// packet, to the current base packet.
|
||||||
|
for (size_t seq_num = last_acked; seq_num < base_seq_num; ++seq_num) {
|
||||||
|
missing_feedback_series.points.emplace_back(
|
||||||
|
config_.GetCallTimeSec(feedback.timestamp),
|
||||||
|
100 + seq_num - last_acked);
|
||||||
|
}
|
||||||
|
last_acked = base_seq_num + transport_feedback.GetPacketStatusCount();
|
||||||
|
|
||||||
|
// Compute loss rate from the transport feedback.
|
||||||
|
auto loss_rate =
|
||||||
|
static_cast<float>((transport_feedback.GetPacketStatusCount() -
|
||||||
|
transport_feedback.GetReceivedPackets().size()) *
|
||||||
|
100.0 / transport_feedback.GetPacketStatusCount());
|
||||||
|
loss_rate_series.points.emplace_back(
|
||||||
|
config_.GetCallTimeSec(feedback.timestamp), loss_rate);
|
||||||
|
|
||||||
|
// Compute loss rate in a window of kObservationWindowSize.
|
||||||
|
if (window_summary.num_packets == 0) {
|
||||||
|
window_summary.base_time = feedback.log_time();
|
||||||
|
}
|
||||||
|
window_summary.num_packets += transport_feedback.GetPacketStatusCount();
|
||||||
|
window_summary.num_lost_packets +=
|
||||||
|
transport_feedback.GetPacketStatusCount() -
|
||||||
|
transport_feedback.GetReceivedPackets().size();
|
||||||
|
|
||||||
|
const Timestamp last_received_time = feedback.log_time();
|
||||||
|
const TimeDelta observation_duration =
|
||||||
|
window_summary.base_time == Timestamp::Zero()
|
||||||
|
? TimeDelta::Zero()
|
||||||
|
: last_received_time - window_summary.base_time;
|
||||||
|
if (observation_duration > kObservationDuration) {
|
||||||
|
last_observation_receive_time = last_received_time;
|
||||||
|
observations.push_back(window_summary);
|
||||||
|
if (observations.size() > kObservationWindowSize) {
|
||||||
|
observations.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute average loss rate in a number of windows.
|
||||||
|
int total_packets = 0;
|
||||||
|
int total_loss = 0;
|
||||||
|
for (const auto& observation : observations) {
|
||||||
|
total_loss += observation.num_lost_packets;
|
||||||
|
total_packets += observation.num_packets;
|
||||||
|
}
|
||||||
|
if (total_packets > 0) {
|
||||||
|
float average_loss_rate = total_loss * 100.0 / total_packets;
|
||||||
|
average_loss_rate_series.points.emplace_back(
|
||||||
|
config_.GetCallTimeSec(feedback.timestamp), average_loss_rate);
|
||||||
|
} else {
|
||||||
|
average_loss_rate_series.points.emplace_back(
|
||||||
|
config_.GetCallTimeSec(feedback.timestamp), 0);
|
||||||
|
}
|
||||||
|
window_summary = PacketLossSummary();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add the data set to the plot.
|
||||||
|
plot->AppendTimeSeriesIfNotEmpty(std::move(loss_rate_series));
|
||||||
|
plot->AppendTimeSeriesIfNotEmpty(std::move(average_loss_rate_series));
|
||||||
|
plot->AppendTimeSeriesIfNotEmpty(std::move(missing_feedback_series));
|
||||||
|
|
||||||
|
plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(),
|
||||||
|
"Time (s)", kLeftMargin, kRightMargin);
|
||||||
|
plot->SetSuggestedYAxis(0, 100, "Loss rate (percent)", kBottomMargin,
|
||||||
|
kTopMargin);
|
||||||
|
plot->SetTitle("Outgoing loss rate (from TWCC feedback)");
|
||||||
|
}
|
||||||
|
|
||||||
void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) {
|
void EventLogAnalyzer::CreateSendSideBweSimulationGraph(Plot* plot) {
|
||||||
using RtpPacketType = LoggedRtpPacketOutgoing;
|
using RtpPacketType = LoggedRtpPacketOutgoing;
|
||||||
using TransportFeedbackType = LoggedRtcpPacketTransportFeedback;
|
using TransportFeedbackType = LoggedRtcpPacketTransportFeedback;
|
||||||
|
|||||||
@ -67,6 +67,7 @@ class EventLogAnalyzer {
|
|||||||
void CreateStreamBitrateGraph(PacketDirection direction, Plot* plot);
|
void CreateStreamBitrateGraph(PacketDirection direction, Plot* plot);
|
||||||
void CreateBitrateAllocationGraph(PacketDirection direction, Plot* plot);
|
void CreateBitrateAllocationGraph(PacketDirection direction, Plot* plot);
|
||||||
|
|
||||||
|
void CreateOutgoingTWCCLossRateGraph(Plot* plot);
|
||||||
void CreateGoogCcSimulationGraph(Plot* plot);
|
void CreateGoogCcSimulationGraph(Plot* plot);
|
||||||
void CreateSendSideBweSimulationGraph(Plot* plot);
|
void CreateSendSideBweSimulationGraph(Plot* plot);
|
||||||
void CreateReceiveSideBweSimulationGraph(Plot* plot);
|
void CreateReceiveSideBweSimulationGraph(Plot* plot);
|
||||||
|
|||||||
@ -227,7 +227,7 @@ int main(int argc, char* argv[]) {
|
|||||||
{"sendside_bwe",
|
{"sendside_bwe",
|
||||||
{"outgoing_packet_sizes", "outgoing_bitrate", "outgoing_stream_bitrate",
|
{"outgoing_packet_sizes", "outgoing_bitrate", "outgoing_stream_bitrate",
|
||||||
"simulated_sendside_bwe", "network_delay_feedback",
|
"simulated_sendside_bwe", "network_delay_feedback",
|
||||||
"fraction_loss_feedback"}},
|
"fraction_loss_feedback", "outgoing_twcc_loss"}},
|
||||||
{"receiveside_bwe",
|
{"receiveside_bwe",
|
||||||
{"incoming_packet_sizes", "incoming_delay", "incoming_loss_rate",
|
{"incoming_packet_sizes", "incoming_delay", "incoming_loss_rate",
|
||||||
"incoming_bitrate", "incoming_stream_bitrate",
|
"incoming_bitrate", "incoming_stream_bitrate",
|
||||||
@ -377,6 +377,9 @@ int main(int argc, char* argv[]) {
|
|||||||
plots.RegisterPlot("simulated_goog_cc", [&](Plot* plot) {
|
plots.RegisterPlot("simulated_goog_cc", [&](Plot* plot) {
|
||||||
analyzer.CreateGoogCcSimulationGraph(plot);
|
analyzer.CreateGoogCcSimulationGraph(plot);
|
||||||
});
|
});
|
||||||
|
plots.RegisterPlot("outgoing_twcc_loss", [&](Plot* plot) {
|
||||||
|
analyzer.CreateOutgoingTWCCLossRateGraph(plot);
|
||||||
|
});
|
||||||
plots.RegisterPlot("network_delay_feedback", [&](Plot* plot) {
|
plots.RegisterPlot("network_delay_feedback", [&](Plot* plot) {
|
||||||
analyzer.CreateNetworkDelayFeedbackGraph(plot);
|
analyzer.CreateNetworkDelayFeedbackGraph(plot);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user