Move network trace calculation from analyzer to rtc_event_log_parser.
Bug: b/116768521 Change-Id: Ibc5643c9c03caa00cc84a5efc628115d414b35f7 Reviewed-on: https://webrtc-review.googlesource.com/102301 Reviewed-by: Björn Terelius <terelius@webrtc.org> Commit-Queue: Christoffer Rodbro <crodbro@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24879}
This commit is contained in:

committed by
Commit Bot

parent
17f4878419
commit
89f64d305e
@ -280,6 +280,7 @@ if (rtc_enable_protobuf) {
|
||||
"../api:libjingle_peerconnection_api",
|
||||
"../call:video_stream_api",
|
||||
"../modules/audio_coding:audio_network_adaptor",
|
||||
"../modules/congestion_controller:transport_feedback",
|
||||
"../modules/remote_bitrate_estimator:remote_bitrate_estimator",
|
||||
"../modules/rtp_rtcp",
|
||||
"../modules/rtp_rtcp:rtp_rtcp_format",
|
||||
|
@ -1,6 +1,7 @@
|
||||
include_rules = [
|
||||
"+call",
|
||||
"+modules/audio_coding/audio_network_adaptor",
|
||||
"+modules/congestion_controller",
|
||||
"+modules/remote_bitrate_estimator/include",
|
||||
"+modules/rtp_rtcp",
|
||||
]
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "api/rtpparameters.h"
|
||||
#include "logging/rtc_event_log/rtc_event_log.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
|
||||
#include "modules/congestion_controller/transport_feedback_adapter.h"
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/byte_io.h"
|
||||
@ -245,6 +246,23 @@ void GetHeaderExtensions(std::vector<RtpExtension>* header_extensions,
|
||||
}
|
||||
}
|
||||
|
||||
void SortPacketFeedbackVectorWithLoss(std::vector<PacketFeedback>* vec) {
|
||||
class LossHandlingPacketFeedbackComparator {
|
||||
public:
|
||||
inline bool operator()(const PacketFeedback& lhs,
|
||||
const PacketFeedback& rhs) {
|
||||
if (lhs.arrival_time_ms != PacketFeedback::kNotReceived &&
|
||||
rhs.arrival_time_ms != PacketFeedback::kNotReceived &&
|
||||
lhs.arrival_time_ms != rhs.arrival_time_ms)
|
||||
return lhs.arrival_time_ms < rhs.arrival_time_ms;
|
||||
if (lhs.send_time_ms != rhs.send_time_ms)
|
||||
return lhs.send_time_ms < rhs.send_time_ms;
|
||||
return lhs.sequence_number < rhs.sequence_number;
|
||||
}
|
||||
};
|
||||
std::sort(vec->begin(), vec->end(), LossHandlingPacketFeedbackComparator());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
LoggedRtcpPacket::LoggedRtcpPacket(uint64_t timestamp_us,
|
||||
@ -1370,4 +1388,74 @@ ParsedRtcEventLogNew::MediaType ParsedRtcEventLogNew::GetMediaType(
|
||||
return MediaType::ANY;
|
||||
}
|
||||
|
||||
const std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
|
||||
const ParsedRtcEventLogNew& parsed_log) {
|
||||
using RtpPacketType = LoggedRtpPacketOutgoing;
|
||||
using TransportFeedbackType = LoggedRtcpPacketTransportFeedback;
|
||||
|
||||
std::multimap<int64_t, const RtpPacketType*> outgoing_rtp;
|
||||
for (const auto& stream : parsed_log.outgoing_rtp_packets_by_ssrc()) {
|
||||
for (const RtpPacketType& rtp_packet : stream.outgoing_packets)
|
||||
outgoing_rtp.insert(
|
||||
std::make_pair(rtp_packet.rtp.log_time_us(), &rtp_packet));
|
||||
}
|
||||
|
||||
const std::vector<TransportFeedbackType>& incoming_rtcp =
|
||||
parsed_log.transport_feedbacks(kIncomingPacket);
|
||||
|
||||
SimulatedClock clock(0);
|
||||
TransportFeedbackAdapter feedback_adapter(&clock);
|
||||
|
||||
auto rtp_iterator = outgoing_rtp.begin();
|
||||
auto rtcp_iterator = incoming_rtcp.begin();
|
||||
|
||||
auto NextRtpTime = [&]() {
|
||||
if (rtp_iterator != outgoing_rtp.end())
|
||||
return static_cast<int64_t>(rtp_iterator->first);
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
};
|
||||
|
||||
auto NextRtcpTime = [&]() {
|
||||
if (rtcp_iterator != incoming_rtcp.end())
|
||||
return static_cast<int64_t>(rtcp_iterator->log_time_us());
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
};
|
||||
|
||||
int64_t time_us = std::min(NextRtpTime(), NextRtcpTime());
|
||||
|
||||
std::vector<MatchedSendArrivalTimes> rtp_rtcp_matched;
|
||||
while (time_us != std::numeric_limits<int64_t>::max()) {
|
||||
clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds());
|
||||
if (clock.TimeInMicroseconds() >= NextRtcpTime()) {
|
||||
RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime());
|
||||
feedback_adapter.OnTransportFeedback(rtcp_iterator->transport_feedback);
|
||||
std::vector<PacketFeedback> feedback =
|
||||
feedback_adapter.GetTransportFeedbackVector();
|
||||
SortPacketFeedbackVectorWithLoss(&feedback);
|
||||
for (const PacketFeedback& packet : feedback) {
|
||||
rtp_rtcp_matched.emplace_back(
|
||||
clock.TimeInMilliseconds(), packet.send_time_ms,
|
||||
packet.arrival_time_ms, packet.payload_size);
|
||||
}
|
||||
++rtcp_iterator;
|
||||
}
|
||||
if (clock.TimeInMicroseconds() >= NextRtpTime()) {
|
||||
RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtpTime());
|
||||
const RtpPacketType& rtp_packet = *rtp_iterator->second;
|
||||
if (rtp_packet.rtp.header.extension.hasTransportSequenceNumber) {
|
||||
feedback_adapter.AddPacket(
|
||||
rtp_packet.rtp.header.ssrc,
|
||||
rtp_packet.rtp.header.extension.transportSequenceNumber,
|
||||
rtp_packet.rtp.total_length, PacedPacketInfo());
|
||||
feedback_adapter.OnSentPacket(
|
||||
rtp_packet.rtp.header.extension.transportSequenceNumber,
|
||||
rtp_packet.rtp.log_time_ms());
|
||||
}
|
||||
++rtp_iterator;
|
||||
}
|
||||
time_us = std::min(NextRtpTime(), NextRtcpTime());
|
||||
}
|
||||
return rtp_rtcp_matched;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -985,6 +985,21 @@ class ParsedRtcEventLogNew {
|
||||
outgoing_rtp_extensions_maps_;
|
||||
};
|
||||
|
||||
struct MatchedSendArrivalTimes {
|
||||
MatchedSendArrivalTimes(int64_t fb, int64_t tx, int64_t rx, int64_t ps)
|
||||
: feedback_arrival_time_ms(fb),
|
||||
send_time_ms(tx),
|
||||
arrival_time_ms(rx),
|
||||
payload_size(ps) {}
|
||||
|
||||
int64_t feedback_arrival_time_ms;
|
||||
int64_t send_time_ms; // PacketFeedback::kNoSendTime for late feedback.
|
||||
int64_t arrival_time_ms; // PacketFeedback::kNotReceived for lost packets.
|
||||
int64_t payload_size;
|
||||
};
|
||||
const std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
|
||||
const ParsedRtcEventLogNew& parsed_log);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_NEW_H_
|
||||
|
@ -1276,83 +1276,27 @@ void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) {
|
||||
}
|
||||
|
||||
void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) {
|
||||
using RtpPacketType = LoggedRtpPacketOutgoing;
|
||||
using TransportFeedbackType = LoggedRtcpPacketTransportFeedback;
|
||||
|
||||
// TODO(terelius): This could be provided by the parser.
|
||||
std::multimap<int64_t, const RtpPacketType*> outgoing_rtp;
|
||||
for (const auto& stream : parsed_log_.outgoing_rtp_packets_by_ssrc()) {
|
||||
for (const RtpPacketType& rtp_packet : stream.outgoing_packets)
|
||||
outgoing_rtp.insert(
|
||||
std::make_pair(rtp_packet.rtp.log_time_us(), &rtp_packet));
|
||||
}
|
||||
|
||||
const std::vector<TransportFeedbackType>& incoming_rtcp =
|
||||
parsed_log_.transport_feedbacks(kIncomingPacket);
|
||||
|
||||
SimulatedClock clock(0);
|
||||
TransportFeedbackAdapter feedback_adapter(&clock);
|
||||
|
||||
TimeSeries late_feedback_series("Late feedback results.", LineStyle::kNone,
|
||||
PointStyle::kHighlight);
|
||||
TimeSeries time_series("Network Delay Change", LineStyle::kLine,
|
||||
PointStyle::kHighlight);
|
||||
int64_t estimated_base_delay_ms = std::numeric_limits<int64_t>::max();
|
||||
|
||||
auto rtp_iterator = outgoing_rtp.begin();
|
||||
auto rtcp_iterator = incoming_rtcp.begin();
|
||||
|
||||
auto NextRtpTime = [&]() {
|
||||
if (rtp_iterator != outgoing_rtp.end())
|
||||
return static_cast<int64_t>(rtp_iterator->first);
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
};
|
||||
|
||||
auto NextRtcpTime = [&]() {
|
||||
if (rtcp_iterator != incoming_rtcp.end())
|
||||
return static_cast<int64_t>(rtcp_iterator->log_time_us());
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
};
|
||||
|
||||
int64_t time_us = std::min(NextRtpTime(), NextRtcpTime());
|
||||
int64_t prev_y = 0;
|
||||
while (time_us != std::numeric_limits<int64_t>::max()) {
|
||||
clock.AdvanceTimeMicroseconds(time_us - clock.TimeInMicroseconds());
|
||||
if (clock.TimeInMicroseconds() >= NextRtcpTime()) {
|
||||
RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime());
|
||||
feedback_adapter.OnTransportFeedback(rtcp_iterator->transport_feedback);
|
||||
std::vector<PacketFeedback> feedback =
|
||||
feedback_adapter.GetTransportFeedbackVector();
|
||||
SortPacketFeedbackVector(&feedback);
|
||||
for (const PacketFeedback& packet : feedback) {
|
||||
float x = ToCallTimeSec(clock.TimeInMicroseconds());
|
||||
if (packet.send_time_ms == PacketFeedback::kNoSendTime) {
|
||||
late_feedback_series.points.emplace_back(x, prev_y);
|
||||
continue;
|
||||
}
|
||||
int64_t y = packet.arrival_time_ms - packet.send_time_ms;
|
||||
prev_y = y;
|
||||
estimated_base_delay_ms = std::min(y, estimated_base_delay_ms);
|
||||
time_series.points.emplace_back(x, y);
|
||||
}
|
||||
++rtcp_iterator;
|
||||
for (auto packet : GetNetworkTrace(parsed_log_)) {
|
||||
if (packet.arrival_time_ms == PacketFeedback::kNotReceived)
|
||||
continue;
|
||||
float x = ToCallTimeSec(1000 * packet.feedback_arrival_time_ms);
|
||||
if (packet.send_time_ms == PacketFeedback::kNoSendTime) {
|
||||
late_feedback_series.points.emplace_back(x, prev_y);
|
||||
continue;
|
||||
}
|
||||
if (clock.TimeInMicroseconds() >= NextRtpTime()) {
|
||||
RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtpTime());
|
||||
const RtpPacketType& rtp_packet = *rtp_iterator->second;
|
||||
if (rtp_packet.rtp.header.extension.hasTransportSequenceNumber) {
|
||||
feedback_adapter.AddPacket(
|
||||
rtp_packet.rtp.header.ssrc,
|
||||
rtp_packet.rtp.header.extension.transportSequenceNumber,
|
||||
rtp_packet.rtp.total_length, PacedPacketInfo());
|
||||
feedback_adapter.OnSentPacket(
|
||||
rtp_packet.rtp.header.extension.transportSequenceNumber,
|
||||
rtp_packet.rtp.log_time_us() / 1000);
|
||||
}
|
||||
++rtp_iterator;
|
||||
}
|
||||
time_us = std::min(NextRtpTime(), NextRtcpTime());
|
||||
int64_t y = packet.arrival_time_ms - packet.send_time_ms;
|
||||
prev_y = y;
|
||||
estimated_base_delay_ms = std::min(y, estimated_base_delay_ms);
|
||||
time_series.points.emplace_back(x, y);
|
||||
}
|
||||
|
||||
// We assume that the base network delay (w/o queues) is the min delay
|
||||
// observed during the call.
|
||||
for (TimeSeriesPoint& point : time_series.points)
|
||||
|
Reference in New Issue
Block a user