This is a follow-up to https://webrtc-review.googlesource.com/c/src/+/106280. This time the whole code base is covered. Some files may have not been fixed though, whenever the IWYU tool was breaking the build. Bug: webrtc:8311 Change-Id: I2c31f552a87e887d33931d46e87b6208b1e483ef Reviewed-on: https://webrtc-review.googlesource.com/c/111965 Commit-Queue: Yves Gerey <yvesg@google.com> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25830}
153 lines
6.0 KiB
C++
153 lines
6.0 KiB
C++
/*
|
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "api/transport/test/network_control_tester.h"
|
|
|
|
#include <algorithm>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "absl/types/optional.h"
|
|
#include "api/transport/network_control.h"
|
|
#include "api/units/data_size.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/logging.h"
|
|
|
|
namespace webrtc {
|
|
namespace test {
|
|
namespace {
|
|
void Update(NetworkControlUpdate* target, const NetworkControlUpdate& update) {
|
|
if (update.congestion_window) {
|
|
RTC_LOG(LS_INFO) << "Received window="
|
|
<< ToString(*update.congestion_window);
|
|
target->congestion_window = update.congestion_window;
|
|
}
|
|
if (update.pacer_config) {
|
|
RTC_LOG(LS_INFO) << "Received pacing at:"
|
|
<< ToString(update.pacer_config->at_time)
|
|
<< ": rate=" << ToString(update.pacer_config->data_rate())
|
|
<< ", pad=" << ToString(update.pacer_config->pad_rate());
|
|
target->pacer_config = update.pacer_config;
|
|
}
|
|
if (update.target_rate) {
|
|
RTC_LOG(LS_INFO)
|
|
<< "Received target at:" << ToString(update.target_rate->at_time)
|
|
<< ": rate=" << ToString(update.target_rate->target_rate) << ", rtt="
|
|
<< ToString(update.target_rate->network_estimate.round_trip_time);
|
|
target->target_rate = update.target_rate;
|
|
}
|
|
for (const auto& probe : update.probe_cluster_configs) {
|
|
target->probe_cluster_configs.push_back(probe);
|
|
RTC_LOG(LS_INFO) << "Received probe at:" << ToString(probe.at_time)
|
|
<< ": target=" << ToString(probe.target_data_rate);
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
SentPacket SimpleTargetRateProducer::ProduceNext(
|
|
const NetworkControlUpdate& cache,
|
|
Timestamp current_time,
|
|
TimeDelta time_delta) {
|
|
DataRate actual_send_rate =
|
|
std::max(cache.target_rate->target_rate, cache.pacer_config->pad_rate());
|
|
SentPacket packet;
|
|
packet.send_time = current_time;
|
|
packet.size = time_delta * actual_send_rate;
|
|
return packet;
|
|
}
|
|
|
|
NetworkControllerTester::NetworkControllerTester(
|
|
NetworkControllerFactoryInterface* factory,
|
|
NetworkControllerConfig initial_config)
|
|
: current_time_(Timestamp::seconds(100000)),
|
|
packet_sequence_number_(1),
|
|
accumulated_buffer_(TimeDelta::Zero()) {
|
|
initial_config.constraints.at_time = current_time_;
|
|
controller_ = factory->Create(initial_config);
|
|
process_interval_ = factory->GetProcessInterval();
|
|
ProcessInterval interval_msg;
|
|
interval_msg.at_time = current_time_;
|
|
Update(&state_, controller_->OnProcessInterval(interval_msg));
|
|
}
|
|
|
|
NetworkControllerTester::~NetworkControllerTester() = default;
|
|
|
|
void NetworkControllerTester::RunSimulation(TimeDelta duration,
|
|
TimeDelta packet_interval,
|
|
DataRate actual_bandwidth,
|
|
TimeDelta propagation_delay,
|
|
PacketProducer next_packet) {
|
|
RTC_CHECK(actual_bandwidth.bps() > 0);
|
|
Timestamp start_time = current_time_;
|
|
Timestamp last_process_time = current_time_;
|
|
while (current_time_ - start_time < duration) {
|
|
bool send_packet = true;
|
|
if (state_.congestion_window && state_.congestion_window->IsFinite()) {
|
|
DataSize data_in_flight = DataSize::Zero();
|
|
for (PacketResult& packet : outstanding_packets_)
|
|
data_in_flight += packet.sent_packet.size;
|
|
if (data_in_flight > *state_.congestion_window)
|
|
send_packet = false;
|
|
}
|
|
|
|
if (send_packet) {
|
|
SentPacket sent_packet;
|
|
sent_packet = next_packet(state_, current_time_, packet_interval);
|
|
sent_packet.sequence_number = packet_sequence_number_++;
|
|
sent_packet.data_in_flight = sent_packet.size;
|
|
for (PacketResult& packet : outstanding_packets_)
|
|
sent_packet.data_in_flight += packet.sent_packet.size;
|
|
Update(&state_, controller_->OnSentPacket(sent_packet));
|
|
|
|
TimeDelta time_in_flight = sent_packet.size / actual_bandwidth;
|
|
accumulated_buffer_ += time_in_flight;
|
|
TimeDelta total_delay = propagation_delay + accumulated_buffer_;
|
|
PacketResult result;
|
|
result.sent_packet = sent_packet;
|
|
result.receive_time = sent_packet.send_time + total_delay;
|
|
|
|
outstanding_packets_.push_back(result);
|
|
}
|
|
|
|
TimeDelta buffer_consumed = std::min(accumulated_buffer_, packet_interval);
|
|
accumulated_buffer_ -= buffer_consumed;
|
|
|
|
if (outstanding_packets_.size() >= 2 &&
|
|
current_time_ >=
|
|
outstanding_packets_[1].receive_time + propagation_delay) {
|
|
TransportPacketsFeedback feedback;
|
|
feedback.prior_in_flight = DataSize::Zero();
|
|
for (PacketResult& packet : outstanding_packets_)
|
|
feedback.prior_in_flight += packet.sent_packet.size;
|
|
while (!outstanding_packets_.empty() &&
|
|
current_time_ >= outstanding_packets_.front().receive_time +
|
|
propagation_delay) {
|
|
feedback.packet_feedbacks.push_back(outstanding_packets_.front());
|
|
outstanding_packets_.pop_front();
|
|
}
|
|
feedback.feedback_time =
|
|
feedback.packet_feedbacks.back().receive_time + propagation_delay;
|
|
feedback.data_in_flight = DataSize::Zero();
|
|
for (PacketResult& packet : outstanding_packets_)
|
|
feedback.data_in_flight += packet.sent_packet.size;
|
|
Update(&state_, controller_->OnTransportPacketsFeedback(feedback));
|
|
}
|
|
current_time_ += packet_interval;
|
|
if (current_time_ - last_process_time > process_interval_) {
|
|
ProcessInterval interval_msg;
|
|
interval_msg.at_time = current_time_;
|
|
Update(&state_, controller_->OnProcessInterval(interval_msg));
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace test
|
|
} // namespace webrtc
|