Makes send time information in feedback non-optional.

This makes it safer to reason about the common case where send
time information is available. We don't have to either assume that
it's available, or check it everywhere the PacketResult struct is used.

To achieve this, a new field is added to TransportPacketsFeedback
and a new interface is introduced to clearly separate which field is
used. A possible followup would be to introduce a separate struct.
That would complicate the signature of ProcessTransportFeedback.

Bug: webrtc:9934
Change-Id: I2b319e4df2b557fbd4de66b812744bca7d91ca15
Reviewed-on: https://webrtc-review.googlesource.com/c/107080
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25465}
This commit is contained in:
Sebastian Jansson
2018-11-01 12:58:25 +01:00
committed by Commit Bot
parent be837ac3bc
commit af6d741fe1
13 changed files with 100 additions and 95 deletions

View File

@ -38,7 +38,7 @@ std::vector<PacketResult> TransportPacketsFeedback::ReceivedWithSendInfo()
const { const {
std::vector<PacketResult> res; std::vector<PacketResult> res;
for (const PacketResult& fb : packet_feedbacks) { for (const PacketResult& fb : packet_feedbacks) {
if (fb.receive_time.IsFinite() && fb.sent_packet.has_value()) { if (fb.receive_time.IsFinite()) {
res.push_back(fb); res.push_back(fb);
} }
} }
@ -48,7 +48,7 @@ std::vector<PacketResult> TransportPacketsFeedback::ReceivedWithSendInfo()
std::vector<PacketResult> TransportPacketsFeedback::LostWithSendInfo() const { std::vector<PacketResult> TransportPacketsFeedback::LostWithSendInfo() const {
std::vector<PacketResult> res; std::vector<PacketResult> res;
for (const PacketResult& fb : packet_feedbacks) { for (const PacketResult& fb : packet_feedbacks) {
if (fb.receive_time.IsPlusInfinity() && fb.sent_packet.has_value()) { if (fb.receive_time.IsPlusInfinity()) {
res.push_back(fb); res.push_back(fb);
} }
} }

View File

@ -126,14 +126,10 @@ struct PacketResult {
PacketResult(const PacketResult&); PacketResult(const PacketResult&);
~PacketResult(); ~PacketResult();
absl::optional<SentPacket> sent_packet; SentPacket sent_packet;
Timestamp receive_time = Timestamp::PlusInfinity(); Timestamp receive_time = Timestamp::PlusInfinity();
// TODO(bugs.webrtc.org/9934): Remove this when sent_packet is made // TODO(bugs.webrtc.org/9934): Remove this when downsrteam projects are ready.
// non-optional. const SentPacket& GetSentPacket() const { return sent_packet; }
const SentPacket& GetSentPacket() const {
RTC_DCHECK(sent_packet.has_value());
return *sent_packet;
}
}; };
struct TransportPacketsFeedback { struct TransportPacketsFeedback {
@ -146,6 +142,9 @@ struct TransportPacketsFeedback {
DataSize prior_in_flight = DataSize::Zero(); DataSize prior_in_flight = DataSize::Zero();
std::vector<PacketResult> packet_feedbacks; std::vector<PacketResult> packet_feedbacks;
// Arrival times for messages without send time information.
std::vector<Timestamp> sendless_arrival_times;
std::vector<PacketResult> ReceivedWithSendInfo() const; std::vector<PacketResult> ReceivedWithSendInfo() const;
std::vector<PacketResult> LostWithSendInfo() const; std::vector<PacketResult> LostWithSendInfo() const;
std::vector<PacketResult> PacketsWithFeedback() const; std::vector<PacketResult> PacketsWithFeedback() const;

View File

@ -87,7 +87,7 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration,
if (state_.congestion_window && state_.congestion_window->IsFinite()) { if (state_.congestion_window && state_.congestion_window->IsFinite()) {
DataSize data_in_flight = DataSize::Zero(); DataSize data_in_flight = DataSize::Zero();
for (PacketResult& packet : outstanding_packets_) for (PacketResult& packet : outstanding_packets_)
data_in_flight += packet.sent_packet->size; data_in_flight += packet.sent_packet.size;
if (data_in_flight > *state_.congestion_window) if (data_in_flight > *state_.congestion_window)
send_packet = false; send_packet = false;
} }
@ -98,7 +98,7 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration,
sent_packet.sequence_number = packet_sequence_number_++; sent_packet.sequence_number = packet_sequence_number_++;
sent_packet.data_in_flight = sent_packet.size; sent_packet.data_in_flight = sent_packet.size;
for (PacketResult& packet : outstanding_packets_) for (PacketResult& packet : outstanding_packets_)
sent_packet.data_in_flight += packet.sent_packet->size; sent_packet.data_in_flight += packet.sent_packet.size;
Update(&state_, controller_->OnSentPacket(sent_packet)); Update(&state_, controller_->OnSentPacket(sent_packet));
TimeDelta time_in_flight = sent_packet.size / actual_bandwidth; TimeDelta time_in_flight = sent_packet.size / actual_bandwidth;
@ -120,7 +120,7 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration,
TransportPacketsFeedback feedback; TransportPacketsFeedback feedback;
feedback.prior_in_flight = DataSize::Zero(); feedback.prior_in_flight = DataSize::Zero();
for (PacketResult& packet : outstanding_packets_) for (PacketResult& packet : outstanding_packets_)
feedback.prior_in_flight += packet.sent_packet->size; feedback.prior_in_flight += packet.sent_packet.size;
while (!outstanding_packets_.empty() && while (!outstanding_packets_.empty() &&
current_time_ >= outstanding_packets_.front().receive_time + current_time_ >= outstanding_packets_.front().receive_time +
propagation_delay) { propagation_delay) {
@ -131,7 +131,7 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration,
feedback.packet_feedbacks.back().receive_time + propagation_delay; feedback.packet_feedbacks.back().receive_time + propagation_delay;
feedback.data_in_flight = DataSize::Zero(); feedback.data_in_flight = DataSize::Zero();
for (PacketResult& packet : outstanding_packets_) for (PacketResult& packet : outstanding_packets_)
feedback.data_in_flight += packet.sent_packet->size; feedback.data_in_flight += packet.sent_packet.size;
Update(&state_, controller_->OnTransportPacketsFeedback(feedback)); Update(&state_, controller_->OnTransportPacketsFeedback(feedback));
} }
current_time_ += packet_interval; current_time_ += packet_interval;

View File

@ -401,16 +401,15 @@ bool BbrNetworkController::IsProbingForMoreBandwidth() const {
NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback( NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback(
TransportPacketsFeedback msg) { TransportPacketsFeedback msg) {
if (msg.packet_feedbacks.empty())
return NetworkControlUpdate();
Timestamp feedback_recv_time = msg.feedback_time; Timestamp feedback_recv_time = msg.feedback_time;
absl::optional<SentPacket> last_sent_packet = SentPacket last_sent_packet = msg.PacketsWithFeedback().back().sent_packet;
msg.PacketsWithFeedback().back().sent_packet;
if (!last_sent_packet.has_value()) { Timestamp send_time = last_sent_packet.send_time;
RTC_LOG(LS_WARNING) << "Last ack packet not in history, no RTT update"; TimeDelta send_delta = feedback_recv_time - send_time;
} else { rtt_stats_.UpdateRtt(send_delta, TimeDelta::Zero(), feedback_recv_time);
Timestamp send_time = last_sent_packet->send_time;
TimeDelta send_delta = feedback_recv_time - send_time;
rtt_stats_.UpdateRtt(send_delta, TimeDelta::Zero(), feedback_recv_time);
}
const DataSize total_data_acked_before = sampler_->total_data_acked(); const DataSize total_data_acked_before = sampler_->total_data_acked();
@ -431,7 +430,7 @@ NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback(
// Input the new data into the BBR model of the connection. // Input the new data into the BBR model of the connection.
if (!acked_packets.empty()) { if (!acked_packets.empty()) {
int64_t last_acked_packet = int64_t last_acked_packet =
acked_packets.rbegin()->sent_packet->sequence_number; acked_packets.rbegin()->sent_packet.sequence_number;
is_round_start = UpdateRoundTripCounter(last_acked_packet); is_round_start = UpdateRoundTripCounter(last_acked_packet);
min_rtt_expired = min_rtt_expired =
@ -472,7 +471,7 @@ NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback(
DataSize data_acked = sampler_->total_data_acked() - total_data_acked_before; DataSize data_acked = sampler_->total_data_acked() - total_data_acked_before;
DataSize data_lost = DataSize::Zero(); DataSize data_lost = DataSize::Zero();
for (const PacketResult& packet : lost_packets) { for (const PacketResult& packet : lost_packets) {
data_lost += packet.sent_packet->size; data_lost += packet.sent_packet.size;
} }
// After the model is updated, recalculate the pacing rate and congestion // After the model is updated, recalculate the pacing rate and congestion
@ -483,7 +482,7 @@ NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback(
// Cleanup internal state. // Cleanup internal state.
if (!acked_packets.empty()) { if (!acked_packets.empty()) {
sampler_->RemoveObsoletePackets( sampler_->RemoveObsoletePackets(
acked_packets.back().sent_packet->sequence_number); acked_packets.back().sent_packet.sequence_number);
} }
return CreateRateUpdate(msg.feedback_time); return CreateRateUpdate(msg.feedback_time);
} }
@ -550,7 +549,7 @@ void BbrNetworkController::EnterProbeBandwidthMode(Timestamp now) {
void BbrNetworkController::DiscardLostPackets( void BbrNetworkController::DiscardLostPackets(
const std::vector<PacketResult>& lost_packets) { const std::vector<PacketResult>& lost_packets) {
for (const PacketResult& packet : lost_packets) { for (const PacketResult& packet : lost_packets) {
sampler_->OnPacketLost(packet.sent_packet->sequence_number); sampler_->OnPacketLost(packet.sent_packet.sequence_number);
} }
} }
@ -569,8 +568,8 @@ bool BbrNetworkController::UpdateBandwidthAndMinRtt(
const std::vector<PacketResult>& acked_packets) { const std::vector<PacketResult>& acked_packets) {
TimeDelta sample_rtt = TimeDelta::PlusInfinity(); TimeDelta sample_rtt = TimeDelta::PlusInfinity();
for (const auto& packet : acked_packets) { for (const auto& packet : acked_packets) {
BandwidthSample bandwidth_sample = sampler_->OnPacketAcknowledged( BandwidthSample bandwidth_sample =
now, packet.sent_packet->sequence_number); sampler_->OnPacketAcknowledged(now, packet.sent_packet.sequence_number);
last_sample_is_app_limited_ = bandwidth_sample.is_app_limited; last_sample_is_app_limited_ = bandwidth_sample.is_app_limited;
if (!bandwidth_sample.rtt.IsZero()) { if (!bandwidth_sample.rtt.IsZero()) {
sample_rtt = std::min(sample_rtt, bandwidth_sample.rtt); sample_rtt = std::min(sample_rtt, bandwidth_sample.rtt);

View File

@ -148,11 +148,8 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
} }
if (delayed_feedback) { if (delayed_feedback) {
++consecutive_delayed_feedbacks_; return OnDelayedFeedback(packet_feedback_vector.back().arrival_time_ms);
if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) {
consecutive_delayed_feedbacks_ = 0;
return OnLongFeedbackDelay(packet_feedback_vector.back().arrival_time_ms);
}
} else { } else {
consecutive_delayed_feedbacks_ = 0; consecutive_delayed_feedbacks_ = 0;
return MaybeUpdateEstimate(acked_bitrate_bps, recovered_from_overuse, return MaybeUpdateEstimate(acked_bitrate_bps, recovered_from_overuse,
@ -161,6 +158,16 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
return Result(); return Result();
} }
DelayBasedBwe::Result DelayBasedBwe::OnDelayedFeedback(
int64_t receive_time_ms) {
++consecutive_delayed_feedbacks_;
if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) {
consecutive_delayed_feedbacks_ = 0;
return OnLongFeedbackDelay(receive_time_ms);
}
return Result();
}
DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay(
int64_t arrival_time_ms) { int64_t arrival_time_ms) {
// Estimate should always be valid since a start bitrate always is set in the // Estimate should always be valid since a start bitrate always is set in the

View File

@ -48,6 +48,7 @@ class DelayBasedBwe {
const std::vector<PacketFeedback>& packet_feedback_vector, const std::vector<PacketFeedback>& packet_feedback_vector,
absl::optional<uint32_t> acked_bitrate_bps, absl::optional<uint32_t> acked_bitrate_bps,
int64_t at_time_ms); int64_t at_time_ms);
Result OnDelayedFeedback(int64_t receive_time_ms);
void OnRttUpdate(int64_t avg_rtt_ms); void OnRttUpdate(int64_t avg_rtt_ms);
bool LatestEstimate(std::vector<uint32_t>* ssrcs, bool LatestEstimate(std::vector<uint32_t>* ssrcs,
uint32_t* bitrate_bps) const; uint32_t* bitrate_bps) const;

View File

@ -106,14 +106,10 @@ std::vector<PacketFeedback> ReceivedPacketsFeedbackAsRtp(
if (fb.receive_time.IsFinite()) { if (fb.receive_time.IsFinite()) {
PacketFeedback pf(fb.receive_time.ms(), 0); PacketFeedback pf(fb.receive_time.ms(), 0);
pf.creation_time_ms = report.feedback_time.ms(); pf.creation_time_ms = report.feedback_time.ms();
if (fb.sent_packet.has_value()) { pf.payload_size = fb.sent_packet.size.bytes();
pf.payload_size = fb.sent_packet->size.bytes(); pf.pacing_info = fb.sent_packet.pacing_info;
pf.pacing_info = fb.sent_packet->pacing_info; pf.send_time_ms = fb.sent_packet.send_time.ms();
pf.send_time_ms = fb.sent_packet->send_time.ms(); pf.unacknowledged_data = fb.sent_packet.prior_unacked_data.bytes();
pf.unacknowledged_data = fb.sent_packet->prior_unacked_data.bytes();
} else {
pf.send_time_ms = PacketFeedback::kNoSendTime;
}
packet_feedback_vector.push_back(pf); packet_feedback_vector.push_back(pf);
} }
} }
@ -382,6 +378,18 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportLossReport(
NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
TransportPacketsFeedback report) { TransportPacketsFeedback report) {
if (report.packet_feedbacks.empty()) {
DelayBasedBwe::Result result = delay_based_bwe_->OnDelayedFeedback(
report.sendless_arrival_times.back().ms());
NetworkControlUpdate update;
if (result.updated) {
bandwidth_estimation_->UpdateDelayBasedEstimate(
report.feedback_time, DataRate::bps(result.target_bitrate_bps));
MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
}
return update;
}
if (congestion_window_pushback_controller_) { if (congestion_window_pushback_controller_) {
congestion_window_pushback_controller_->UpdateOutstandingData( congestion_window_pushback_controller_->UpdateOutstandingData(
report.data_in_flight.bytes()); report.data_in_flight.bytes());
@ -396,7 +404,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
for (const auto& feedback : feedbacks) { for (const auto& feedback : feedbacks) {
TimeDelta feedback_rtt = TimeDelta feedback_rtt =
report.feedback_time - feedback.sent_packet->send_time; report.feedback_time - feedback.sent_packet.send_time;
TimeDelta min_pending_time = feedback.receive_time - max_recv_time; TimeDelta min_pending_time = feedback.receive_time - max_recv_time;
TimeDelta propagation_rtt = feedback_rtt - min_pending_time; TimeDelta propagation_rtt = feedback_rtt - min_pending_time;
max_feedback_rtt = std::max(max_feedback_rtt, feedback_rtt); max_feedback_rtt = std::max(max_feedback_rtt, feedback_rtt);
@ -423,7 +431,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
for (const auto& packet_feedback : feedbacks) { for (const auto& packet_feedback : feedbacks) {
TimeDelta pending_time = packet_feedback.receive_time - max_recv_time; TimeDelta pending_time = packet_feedback.receive_time - max_recv_time;
TimeDelta rtt = report.feedback_time - TimeDelta rtt = report.feedback_time -
packet_feedback.sent_packet->send_time - pending_time; packet_feedback.sent_packet.send_time - pending_time;
// Value used for predicting NACK round trip time in FEC controller. // Value used for predicting NACK round trip time in FEC controller.
feedback_min_rtt = std::min(rtt, feedback_min_rtt); feedback_min_rtt = std::min(rtt, feedback_min_rtt);
} }

View File

@ -84,9 +84,9 @@ class GoogCcNetworkControllerTest : public ::testing::Test {
PacedPacketInfo pacing_info) { PacedPacketInfo pacing_info) {
PacketResult packet_result; PacketResult packet_result;
packet_result.sent_packet = SentPacket(); packet_result.sent_packet = SentPacket();
packet_result.sent_packet->send_time = Timestamp::ms(send_time_ms); packet_result.sent_packet.send_time = Timestamp::ms(send_time_ms);
packet_result.sent_packet->size = DataSize::bytes(payload_size); packet_result.sent_packet.size = DataSize::bytes(payload_size);
packet_result.sent_packet->pacing_info = pacing_info; packet_result.sent_packet.pacing_info = pacing_info;
packet_result.receive_time = Timestamp::ms(arrival_time_ms); packet_result.receive_time = Timestamp::ms(arrival_time_ms);
return packet_result; return packet_result;
} }
@ -122,7 +122,7 @@ class GoogCcNetworkControllerTest : public ::testing::Test {
CreateResult(current_time_.ms() + delay_buildup, current_time_.ms(), CreateResult(current_time_.ms() + delay_buildup, current_time_.ms(),
kPayloadSize, PacedPacketInfo()); kPayloadSize, PacedPacketInfo());
delay_buildup += delay; delay_buildup += delay;
controller_->OnSentPacket(*packet.sent_packet); controller_->OnSentPacket(packet.sent_packet);
TransportPacketsFeedback feedback; TransportPacketsFeedback feedback;
feedback.feedback_time = packet.receive_time; feedback.feedback_time = packet.receive_time;
feedback.packet_feedbacks.push_back(packet); feedback.packet_feedbacks.push_back(packet);
@ -213,16 +213,13 @@ TEST_F(GoogCcNetworkControllerTest, LongFeedbackDelays) {
packets.push_back( packets.push_back(
CreateResult(i * 100 + 40, 2 * i * 100 + 40, 1500, kPacingInfo1)); CreateResult(i * 100 + 40, 2 * i * 100 + 40, 1500, kPacingInfo1));
TransportPacketsFeedback feedback;
for (PacketResult& packet : packets) { for (PacketResult& packet : packets) {
controller_->OnSentPacket(*packet.sent_packet); controller_->OnSentPacket(packet.sent_packet);
// Simulate packet timeout feedback.sendless_arrival_times.push_back(packet.receive_time);
packet.sent_packet = absl::nullopt;
} }
TransportPacketsFeedback feedback;
feedback.feedback_time = packets[0].receive_time; feedback.feedback_time = packets[0].receive_time;
feedback.packet_feedbacks = packets;
AdvanceTimeMilliseconds(kFeedbackTimeoutMs); AdvanceTimeMilliseconds(kFeedbackTimeoutMs);
SentPacket later_packet; SentPacket later_packet;
later_packet.send_time = Timestamp::ms(kFeedbackTimeoutMs + i * 200 + 40); later_packet.send_time = Timestamp::ms(kFeedbackTimeoutMs + i * 200 + 40);
@ -246,7 +243,7 @@ TEST_F(GoogCcNetworkControllerTest, LongFeedbackDelays) {
packets.push_back(CreateResult(140, 240, 1500, kPacingInfo1)); packets.push_back(CreateResult(140, 240, 1500, kPacingInfo1));
for (const PacketResult& packet : packets) for (const PacketResult& packet : packets)
controller_->OnSentPacket(*packet.sent_packet); controller_->OnSentPacket(packet.sent_packet);
TransportPacketsFeedback feedback; TransportPacketsFeedback feedback;
feedback.feedback_time = packets[0].receive_time; feedback.feedback_time = packets[0].receive_time;

View File

@ -31,25 +31,24 @@ PccMonitorInterval::PccMonitorInterval(const PccMonitorInterval& other) =
void PccMonitorInterval::OnPacketsFeedback( void PccMonitorInterval::OnPacketsFeedback(
const std::vector<PacketResult>& packets_results) { const std::vector<PacketResult>& packets_results) {
for (const PacketResult& packet_result : packets_results) { for (const PacketResult& packet_result : packets_results) {
if (!packet_result.sent_packet.has_value() || if (packet_result.sent_packet.send_time <= start_time_) {
packet_result.sent_packet->send_time <= start_time_) {
continue; continue;
} }
// Here we assume that if some packets are reordered with packets sent // Here we assume that if some packets are reordered with packets sent
// after the end of the monitor interval, then they are lost. (Otherwise // after the end of the monitor interval, then they are lost. (Otherwise
// it is not clear how long should we wait for packets feedback to arrive). // it is not clear how long should we wait for packets feedback to arrive).
if (packet_result.sent_packet->send_time > if (packet_result.sent_packet.send_time >
start_time_ + interval_duration_) { start_time_ + interval_duration_) {
feedback_collection_done_ = true; feedback_collection_done_ = true;
return; return;
} }
if (packet_result.receive_time.IsInfinite()) { if (packet_result.receive_time.IsInfinite()) {
lost_packets_sent_time_.push_back(packet_result.sent_packet->send_time); lost_packets_sent_time_.push_back(packet_result.sent_packet.send_time);
} else { } else {
received_packets_.push_back( received_packets_.push_back(
{packet_result.receive_time - packet_result.sent_packet->send_time, {packet_result.receive_time - packet_result.sent_packet.send_time,
packet_result.sent_packet->send_time}); packet_result.sent_packet.send_time});
received_packets_size_ += packet_result.sent_packet->size; received_packets_size_ += packet_result.sent_packet.size;
} }
} }
} }

View File

@ -148,7 +148,7 @@ NetworkControlUpdate PccNetworkController::OnSentPacket(SentPacket msg) {
if (IsTimeoutExpired(msg.send_time)) { if (IsTimeoutExpired(msg.send_time)) {
DataSize received_size = DataSize::Zero(); DataSize received_size = DataSize::Zero();
for (size_t i = 1; i < last_received_packets_.size(); ++i) { for (size_t i = 1; i < last_received_packets_.size(); ++i) {
received_size += last_received_packets_[i].sent_packet->size; received_size += last_received_packets_[i].sent_packet.size;
} }
TimeDelta sending_time = TimeDelta::Zero(); TimeDelta sending_time = TimeDelta::Zero();
if (last_received_packets_.size() > 0) if (last_received_packets_.size() > 0)
@ -166,7 +166,7 @@ NetworkControlUpdate PccNetworkController::OnSentPacket(SentPacket msg) {
msg.send_time - start_time_ >= kStartupDuration) { msg.send_time - start_time_ >= kStartupDuration) {
DataSize received_size = DataSize::Zero(); DataSize received_size = DataSize::Zero();
for (size_t i = 1; i < last_received_packets_.size(); ++i) { for (size_t i = 1; i < last_received_packets_.size(); ++i) {
received_size += last_received_packets_[i].sent_packet->size; received_size += last_received_packets_[i].sent_packet.size;
} }
TimeDelta sending_time = TimeDelta::Zero(); TimeDelta sending_time = TimeDelta::Zero();
if (last_received_packets_.size() > 0) if (last_received_packets_.size() > 0)
@ -260,6 +260,8 @@ bool PccNetworkController::IsFeedbackCollectionDone() const {
NetworkControlUpdate PccNetworkController::OnTransportPacketsFeedback( NetworkControlUpdate PccNetworkController::OnTransportPacketsFeedback(
TransportPacketsFeedback msg) { TransportPacketsFeedback msg) {
if (msg.packet_feedbacks.empty())
return NetworkControlUpdate();
// Save packets to last_received_packets_ array. // Save packets to last_received_packets_ array.
for (const PacketResult& packet_result : msg.ReceivedWithSendInfo()) { for (const PacketResult& packet_result : msg.ReceivedWithSendInfo()) {
last_received_packets_.push_back(packet_result); last_received_packets_.push_back(packet_result);

View File

@ -23,12 +23,11 @@ void RttTracker::OnPacketsFeedback(
Timestamp feedback_received_time) { Timestamp feedback_received_time) {
TimeDelta packet_rtt = TimeDelta::MinusInfinity(); TimeDelta packet_rtt = TimeDelta::MinusInfinity();
for (const PacketResult& packet_result : packet_feedbacks) { for (const PacketResult& packet_result : packet_feedbacks) {
if (!packet_result.sent_packet.has_value() || if (packet_result.receive_time.IsInfinite())
packet_result.receive_time.IsInfinite())
continue; continue;
packet_rtt = std::max<TimeDelta>( packet_rtt = std::max<TimeDelta>(
packet_rtt, packet_rtt,
feedback_received_time - packet_result.sent_packet->send_time); feedback_received_time - packet_result.sent_packet.send_time);
} }
if (packet_rtt.IsFinite()) if (packet_rtt.IsFinite())
rtt_estimate_ = (1 - alpha_) * rtt_estimate_ + alpha_ * packet_rtt; rtt_estimate_ = (1 - alpha_) * rtt_estimate_ + alpha_ * packet_rtt;

View File

@ -27,35 +27,19 @@ void SortPacketFeedbackVector(std::vector<webrtc::PacketFeedback>* input) {
PacketResult NetworkPacketFeedbackFromRtpPacketFeedback( PacketResult NetworkPacketFeedbackFromRtpPacketFeedback(
const webrtc::PacketFeedback& pf) { const webrtc::PacketFeedback& pf) {
PacketResult feedback; PacketResult feedback;
if (pf.arrival_time_ms == webrtc::PacketFeedback::kNotReceived) if (pf.arrival_time_ms == webrtc::PacketFeedback::kNotReceived) {
feedback.receive_time = Timestamp::PlusInfinity(); feedback.receive_time = Timestamp::PlusInfinity();
else } else {
feedback.receive_time = Timestamp::ms(pf.arrival_time_ms); feedback.receive_time = Timestamp::ms(pf.arrival_time_ms);
if (pf.send_time_ms != webrtc::PacketFeedback::kNoSendTime) {
feedback.sent_packet = SentPacket();
feedback.sent_packet->sequence_number = pf.long_sequence_number;
feedback.sent_packet->send_time = Timestamp::ms(pf.send_time_ms);
feedback.sent_packet->size = DataSize::bytes(pf.payload_size);
feedback.sent_packet->pacing_info = pf.pacing_info;
feedback.sent_packet->prior_unacked_data =
DataSize::bytes(pf.unacknowledged_data);
} }
feedback.sent_packet.sequence_number = pf.long_sequence_number;
feedback.sent_packet.send_time = Timestamp::ms(pf.send_time_ms);
feedback.sent_packet.size = DataSize::bytes(pf.payload_size);
feedback.sent_packet.pacing_info = pf.pacing_info;
feedback.sent_packet.prior_unacked_data =
DataSize::bytes(pf.unacknowledged_data);
return feedback; return feedback;
} }
std::vector<PacketResult> PacketResultsFromRtpFeedbackVector(
const std::vector<PacketFeedback>& feedback_vector) {
RTC_DCHECK(std::is_sorted(feedback_vector.begin(), feedback_vector.end(),
PacketFeedbackComparator()));
std::vector<PacketResult> packet_feedbacks;
packet_feedbacks.reserve(feedback_vector.size());
for (const PacketFeedback& rtp_feedback : feedback_vector) {
auto feedback = NetworkPacketFeedbackFromRtpPacketFeedback(rtp_feedback);
packet_feedbacks.push_back(feedback);
}
return packet_feedbacks;
}
} // namespace } // namespace
const int64_t kNoTimestamp = -1; const int64_t kNoTimestamp = -1;
const int64_t kSendTimeHistoryWindowMs = 60000; const int64_t kSendTimeHistoryWindowMs = 60000;
@ -151,7 +135,17 @@ TransportFeedbackAdapter::ProcessTransportFeedback(
SortPacketFeedbackVector(&feedback_vector); SortPacketFeedbackVector(&feedback_vector);
TransportPacketsFeedback msg; TransportPacketsFeedback msg;
msg.packet_feedbacks = PacketResultsFromRtpFeedbackVector(feedback_vector); for (const PacketFeedback& rtp_feedback : feedback_vector) {
if (rtp_feedback.send_time_ms != PacketFeedback::kNoSendTime) {
auto feedback = NetworkPacketFeedbackFromRtpPacketFeedback(rtp_feedback);
msg.packet_feedbacks.push_back(feedback);
} else if (rtp_feedback.arrival_time_ms == PacketFeedback::kNotReceived) {
msg.sendless_arrival_times.push_back(Timestamp::PlusInfinity());
} else {
msg.sendless_arrival_times.push_back(
Timestamp::ms(rtp_feedback.arrival_time_ms));
}
}
msg.feedback_time = Timestamp::ms(feedback_time_ms); msg.feedback_time = Timestamp::ms(feedback_time_ms);
msg.prior_in_flight = prior_in_flight; msg.prior_in_flight = prior_in_flight;
msg.data_in_flight = GetOutstandingData(); msg.data_in_flight = GetOutstandingData();

View File

@ -144,7 +144,7 @@ TransportPacketsFeedback SimulatedSender::PullFeedbackReport(
} }
} }
data_in_flight_ -= feedback.sent_packet->size; data_in_flight_ -= feedback.sent_packet.size;
report.packet_feedbacks.push_back(feedback); report.packet_feedbacks.push_back(feedback);
} }
} }
@ -284,9 +284,9 @@ bool SimulatedTimeClient::TryDeliverPacket(rtc::CopyOnWriteBuffer raw_buffer,
for (PacketResult& feedback : report.packet_feedbacks) { for (PacketResult& feedback : report.packet_feedbacks) {
if (packet_log_) if (packet_log_)
fprintf(packet_log_, "%" PRId64 " %" PRId64 " %.3lf %.3lf %.3lf\n", fprintf(packet_log_, "%" PRId64 " %" PRId64 " %.3lf %.3lf %.3lf\n",
feedback.sent_packet->sequence_number, feedback.sent_packet.sequence_number,
feedback.sent_packet->size.bytes(), feedback.sent_packet.size.bytes(),
feedback.sent_packet->send_time.seconds<double>(), feedback.sent_packet.send_time.seconds<double>(),
feedback.receive_time.seconds<double>(), feedback.receive_time.seconds<double>(),
at_time.seconds<double>()); at_time.seconds<double>());
} }