Move SimulatedNetwork class to separate file.
Bug: webrtc:9467 Change-Id: Iaf91f27ea7ad9e9e59991bbeb0ef3868578e6a8f Reviewed-on: https://webrtc-review.googlesource.com/92884 Reviewed-by: Niels Moller <nisse@webrtc.org> Commit-Queue: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24221}
This commit is contained in:

committed by
Commit Bot

parent
d528ad542e
commit
f96b1ca609
@ -247,6 +247,19 @@ rtc_source_set("video_stream_api") {
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("simulated_network") {
|
||||
sources = [
|
||||
"simulated_network.cc",
|
||||
"simulated_network.h",
|
||||
]
|
||||
deps = [
|
||||
"../api:simulated_network_api",
|
||||
"../rtc_base:rtc_base_approved",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("fake_network") {
|
||||
sources = [
|
||||
"fake_network_pipe.cc",
|
||||
@ -254,6 +267,7 @@ rtc_source_set("fake_network") {
|
||||
]
|
||||
deps = [
|
||||
":call_interfaces",
|
||||
":simulated_network",
|
||||
"..:webrtc_common",
|
||||
"../api:simulated_network_api",
|
||||
"../api:transport_api",
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
@ -159,98 +158,10 @@ void FakeNetworkPipe::SetClockOffset(int64_t offset_ms) {
|
||||
clock_offset_ms_ = offset_ms;
|
||||
}
|
||||
|
||||
SimulatedNetwork::SimulatedNetwork(SimulatedNetwork::Config config,
|
||||
uint64_t random_seed)
|
||||
: random_(random_seed), bursting_(false) {
|
||||
SetConfig(config);
|
||||
}
|
||||
|
||||
SimulatedNetwork::~SimulatedNetwork() = default;
|
||||
|
||||
void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) {
|
||||
network_simulation_->SetConfig(config);
|
||||
}
|
||||
|
||||
void SimulatedNetwork::SetConfig(const SimulatedNetwork::Config& config) {
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
config_ = config; // Shallow copy of the struct.
|
||||
double prob_loss = config.loss_percent / 100.0;
|
||||
if (config_.avg_burst_loss_length == -1) {
|
||||
// Uniform loss
|
||||
prob_loss_bursting_ = prob_loss;
|
||||
prob_start_bursting_ = prob_loss;
|
||||
} else {
|
||||
// Lose packets according to a gilbert-elliot model.
|
||||
int avg_burst_loss_length = config.avg_burst_loss_length;
|
||||
int min_avg_burst_loss_length = std::ceil(prob_loss / (1 - prob_loss));
|
||||
|
||||
RTC_CHECK_GT(avg_burst_loss_length, min_avg_burst_loss_length)
|
||||
<< "For a total packet loss of " << config.loss_percent << "%% then"
|
||||
<< " avg_burst_loss_length must be " << min_avg_burst_loss_length + 1
|
||||
<< " or higher.";
|
||||
|
||||
prob_loss_bursting_ = (1.0 - 1.0 / avg_burst_loss_length);
|
||||
prob_start_bursting_ = prob_loss / (1 - prob_loss) / avg_burst_loss_length;
|
||||
}
|
||||
}
|
||||
|
||||
void SimulatedNetwork::PauseTransmissionUntil(int64_t until_us) {
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
pause_transmission_until_us_ = until_us;
|
||||
}
|
||||
|
||||
bool SimulatedNetwork::EnqueuePacket(PacketInFlightInfo packet) {
|
||||
Config config;
|
||||
{
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
config = config_;
|
||||
}
|
||||
rtc::CritScope crit(&process_lock_);
|
||||
if (config.queue_length_packets > 0 &&
|
||||
capacity_link_.size() >= config.queue_length_packets) {
|
||||
// Too many packet on the link, drop this one.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delay introduced by the link capacity.
|
||||
int64_t capacity_delay_ms = 0;
|
||||
if (config.link_capacity_kbps > 0) {
|
||||
// Using bytes per millisecond to avoid losing precision.
|
||||
const int64_t bytes_per_millisecond = config.link_capacity_kbps / 8;
|
||||
// To round to the closest millisecond we add half a milliseconds worth of
|
||||
// bytes to the delay calculation.
|
||||
capacity_delay_ms = (packet.size + capacity_delay_error_bytes_ +
|
||||
bytes_per_millisecond / 2) /
|
||||
bytes_per_millisecond;
|
||||
capacity_delay_error_bytes_ +=
|
||||
packet.size - capacity_delay_ms * bytes_per_millisecond;
|
||||
}
|
||||
int64_t network_start_time_us = packet.send_time_us;
|
||||
|
||||
{
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
if (pause_transmission_until_us_) {
|
||||
network_start_time_us =
|
||||
std::max(network_start_time_us, *pause_transmission_until_us_);
|
||||
pause_transmission_until_us_.reset();
|
||||
}
|
||||
}
|
||||
// Check if there already are packets on the link and change network start
|
||||
// time forward if there is.
|
||||
if (!capacity_link_.empty() &&
|
||||
network_start_time_us < capacity_link_.back().arrival_time_us)
|
||||
network_start_time_us = capacity_link_.back().arrival_time_us;
|
||||
|
||||
int64_t arrival_time_us = network_start_time_us + capacity_delay_ms * 1000;
|
||||
capacity_link_.push({packet, arrival_time_us});
|
||||
return true;
|
||||
}
|
||||
|
||||
absl::optional<int64_t> SimulatedNetwork::NextDeliveryTimeUs() const {
|
||||
if (!delay_link_.empty())
|
||||
return delay_link_.begin()->arrival_time_us;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
FakeNetworkPipe::StoredPacket::StoredPacket(NetworkPacket&& packet)
|
||||
: packet(std::move(packet)) {}
|
||||
@ -320,85 +231,6 @@ size_t FakeNetworkPipe::SentPackets() {
|
||||
return sent_packets_;
|
||||
}
|
||||
|
||||
std::vector<PacketDeliveryInfo> SimulatedNetwork::DequeueDeliverablePackets(
|
||||
int64_t receive_time_us) {
|
||||
int64_t time_now_us = receive_time_us;
|
||||
Config config;
|
||||
double prob_loss_bursting;
|
||||
double prob_start_bursting;
|
||||
{
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
config = config_;
|
||||
prob_loss_bursting = prob_loss_bursting_;
|
||||
prob_start_bursting = prob_start_bursting_;
|
||||
}
|
||||
{
|
||||
rtc::CritScope crit(&process_lock_);
|
||||
// Check the capacity link first.
|
||||
if (!capacity_link_.empty()) {
|
||||
int64_t last_arrival_time_us =
|
||||
delay_link_.empty() ? -1 : delay_link_.back().arrival_time_us;
|
||||
bool needs_sort = false;
|
||||
while (!capacity_link_.empty() &&
|
||||
time_now_us >= capacity_link_.front().arrival_time_us) {
|
||||
// Time to get this packet.
|
||||
PacketInfo packet = std::move(capacity_link_.front());
|
||||
capacity_link_.pop();
|
||||
|
||||
// Drop packets at an average rate of |config_.loss_percent| with
|
||||
// and average loss burst length of |config_.avg_burst_loss_length|.
|
||||
if ((bursting_ && random_.Rand<double>() < prob_loss_bursting) ||
|
||||
(!bursting_ && random_.Rand<double>() < prob_start_bursting)) {
|
||||
bursting_ = true;
|
||||
continue;
|
||||
} else {
|
||||
bursting_ = false;
|
||||
}
|
||||
|
||||
int64_t arrival_time_jitter_us = std::max(
|
||||
random_.Gaussian(config.queue_delay_ms * 1000,
|
||||
config.delay_standard_deviation_ms * 1000),
|
||||
0.0);
|
||||
|
||||
// If reordering is not allowed then adjust arrival_time_jitter
|
||||
// to make sure all packets are sent in order.
|
||||
if (!config.allow_reordering && !delay_link_.empty() &&
|
||||
packet.arrival_time_us + arrival_time_jitter_us <
|
||||
last_arrival_time_us) {
|
||||
arrival_time_jitter_us =
|
||||
last_arrival_time_us - packet.arrival_time_us;
|
||||
}
|
||||
packet.arrival_time_us += arrival_time_jitter_us;
|
||||
if (packet.arrival_time_us >= last_arrival_time_us) {
|
||||
last_arrival_time_us = packet.arrival_time_us;
|
||||
} else {
|
||||
needs_sort = true;
|
||||
}
|
||||
delay_link_.emplace_back(std::move(packet));
|
||||
}
|
||||
|
||||
if (needs_sort) {
|
||||
// Packet(s) arrived out of order, make sure list is sorted.
|
||||
std::sort(delay_link_.begin(), delay_link_.end(),
|
||||
[](const PacketInfo& p1, const PacketInfo& p2) {
|
||||
return p1.arrival_time_us < p2.arrival_time_us;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PacketDeliveryInfo> packets_to_deliver;
|
||||
// Check the extra delay queue.
|
||||
while (!delay_link_.empty() &&
|
||||
time_now_us >= delay_link_.front().arrival_time_us) {
|
||||
PacketInfo packet_info = delay_link_.front();
|
||||
packets_to_deliver.emplace_back(
|
||||
PacketDeliveryInfo(packet_info.packet, packet_info.arrival_time_us));
|
||||
delay_link_.pop_front();
|
||||
}
|
||||
return packets_to_deliver;
|
||||
}
|
||||
}
|
||||
|
||||
void FakeNetworkPipe::Process() {
|
||||
int64_t time_now_us = clock_->TimeInMicroseconds();
|
||||
std::queue<NetworkPacket> packets_to_deliver;
|
||||
|
@ -22,11 +22,11 @@
|
||||
#include "api/call/transport.h"
|
||||
#include "api/test/simulated_network.h"
|
||||
#include "call/call.h"
|
||||
#include "call/simulated_network.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/include/module.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/criticalsection.h"
|
||||
#include "rtc_base/random.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -98,58 +98,6 @@ class NetworkPacket {
|
||||
absl::optional<int64_t> packet_time_us_;
|
||||
};
|
||||
|
||||
// Class simulating a network link. This is a simple and naive solution just
|
||||
// faking capacity and adding an extra transport delay in addition to the
|
||||
// capacity introduced delay.
|
||||
class SimulatedNetwork : public NetworkSimulationInterface {
|
||||
public:
|
||||
using Config = NetworkSimulationInterface::SimulatedNetworkConfig;
|
||||
explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
|
||||
~SimulatedNetwork() override;
|
||||
|
||||
// Sets a new configuration. This won't affect packets already in the pipe.
|
||||
void SetConfig(const Config& config);
|
||||
void PauseTransmissionUntil(int64_t until_us);
|
||||
|
||||
// NetworkSimulationInterface
|
||||
bool EnqueuePacket(PacketInFlightInfo packet) override;
|
||||
std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
|
||||
int64_t receive_time_us) override;
|
||||
|
||||
absl::optional<int64_t> NextDeliveryTimeUs() const override;
|
||||
|
||||
private:
|
||||
struct PacketInfo {
|
||||
PacketInFlightInfo packet;
|
||||
int64_t arrival_time_us;
|
||||
};
|
||||
rtc::CriticalSection config_lock_;
|
||||
|
||||
// |process_lock| guards the data structures involved in delay and loss
|
||||
// processes, such as the packet queues.
|
||||
rtc::CriticalSection process_lock_;
|
||||
std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_lock_);
|
||||
Random random_;
|
||||
|
||||
std::deque<PacketInfo> delay_link_;
|
||||
|
||||
// Link configuration.
|
||||
Config config_ RTC_GUARDED_BY(config_lock_);
|
||||
absl::optional<int64_t> pause_transmission_until_us_
|
||||
RTC_GUARDED_BY(config_lock_);
|
||||
|
||||
// Are we currently dropping a burst of packets?
|
||||
bool bursting_;
|
||||
|
||||
// The probability to drop the packet if we are currently dropping a
|
||||
// burst of packet
|
||||
double prob_loss_bursting_ RTC_GUARDED_BY(config_lock_);
|
||||
|
||||
// The probability to drop a burst of packets.
|
||||
double prob_start_bursting_ RTC_GUARDED_BY(config_lock_);
|
||||
int64_t capacity_delay_error_bytes_ = 0;
|
||||
};
|
||||
|
||||
// Class faking a network link, internally is uses an implementation of a
|
||||
// SimulatedNetworkInterface to simulate network behavior.
|
||||
class FakeNetworkPipe : public Transport, public PacketReceiver, public Module {
|
||||
|
186
call/simulated_network.cc
Normal file
186
call/simulated_network.cc
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 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 "call/simulated_network.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
SimulatedNetwork::SimulatedNetwork(SimulatedNetwork::Config config,
|
||||
uint64_t random_seed)
|
||||
: random_(random_seed), bursting_(false) {
|
||||
SetConfig(config);
|
||||
}
|
||||
|
||||
SimulatedNetwork::~SimulatedNetwork() = default;
|
||||
|
||||
void SimulatedNetwork::SetConfig(const SimulatedNetwork::Config& config) {
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
config_ = config; // Shallow copy of the struct.
|
||||
double prob_loss = config.loss_percent / 100.0;
|
||||
if (config_.avg_burst_loss_length == -1) {
|
||||
// Uniform loss
|
||||
prob_loss_bursting_ = prob_loss;
|
||||
prob_start_bursting_ = prob_loss;
|
||||
} else {
|
||||
// Lose packets according to a gilbert-elliot model.
|
||||
int avg_burst_loss_length = config.avg_burst_loss_length;
|
||||
int min_avg_burst_loss_length = std::ceil(prob_loss / (1 - prob_loss));
|
||||
|
||||
RTC_CHECK_GT(avg_burst_loss_length, min_avg_burst_loss_length)
|
||||
<< "For a total packet loss of " << config.loss_percent << "%% then"
|
||||
<< " avg_burst_loss_length must be " << min_avg_burst_loss_length + 1
|
||||
<< " or higher.";
|
||||
|
||||
prob_loss_bursting_ = (1.0 - 1.0 / avg_burst_loss_length);
|
||||
prob_start_bursting_ = prob_loss / (1 - prob_loss) / avg_burst_loss_length;
|
||||
}
|
||||
}
|
||||
|
||||
void SimulatedNetwork::PauseTransmissionUntil(int64_t until_us) {
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
pause_transmission_until_us_ = until_us;
|
||||
}
|
||||
|
||||
bool SimulatedNetwork::EnqueuePacket(PacketInFlightInfo packet) {
|
||||
Config config;
|
||||
{
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
config = config_;
|
||||
}
|
||||
rtc::CritScope crit(&process_lock_);
|
||||
if (config.queue_length_packets > 0 &&
|
||||
capacity_link_.size() >= config.queue_length_packets) {
|
||||
// Too many packet on the link, drop this one.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delay introduced by the link capacity.
|
||||
int64_t capacity_delay_ms = 0;
|
||||
if (config.link_capacity_kbps > 0) {
|
||||
// Using bytes per millisecond to avoid losing precision.
|
||||
const int64_t bytes_per_millisecond = config.link_capacity_kbps / 8;
|
||||
// To round to the closest millisecond we add half a milliseconds worth of
|
||||
// bytes to the delay calculation.
|
||||
capacity_delay_ms = (packet.size + capacity_delay_error_bytes_ +
|
||||
bytes_per_millisecond / 2) /
|
||||
bytes_per_millisecond;
|
||||
capacity_delay_error_bytes_ +=
|
||||
packet.size - capacity_delay_ms * bytes_per_millisecond;
|
||||
}
|
||||
int64_t network_start_time_us = packet.send_time_us;
|
||||
|
||||
{
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
if (pause_transmission_until_us_) {
|
||||
network_start_time_us =
|
||||
std::max(network_start_time_us, *pause_transmission_until_us_);
|
||||
pause_transmission_until_us_.reset();
|
||||
}
|
||||
}
|
||||
// Check if there already are packets on the link and change network start
|
||||
// time forward if there is.
|
||||
if (!capacity_link_.empty() &&
|
||||
network_start_time_us < capacity_link_.back().arrival_time_us)
|
||||
network_start_time_us = capacity_link_.back().arrival_time_us;
|
||||
|
||||
int64_t arrival_time_us = network_start_time_us + capacity_delay_ms * 1000;
|
||||
capacity_link_.push({packet, arrival_time_us});
|
||||
return true;
|
||||
}
|
||||
|
||||
absl::optional<int64_t> SimulatedNetwork::NextDeliveryTimeUs() const {
|
||||
if (!delay_link_.empty())
|
||||
return delay_link_.begin()->arrival_time_us;
|
||||
return absl::nullopt;
|
||||
}
|
||||
std::vector<PacketDeliveryInfo> SimulatedNetwork::DequeueDeliverablePackets(
|
||||
int64_t receive_time_us) {
|
||||
int64_t time_now_us = receive_time_us;
|
||||
Config config;
|
||||
double prob_loss_bursting;
|
||||
double prob_start_bursting;
|
||||
{
|
||||
rtc::CritScope crit(&config_lock_);
|
||||
config = config_;
|
||||
prob_loss_bursting = prob_loss_bursting_;
|
||||
prob_start_bursting = prob_start_bursting_;
|
||||
}
|
||||
{
|
||||
rtc::CritScope crit(&process_lock_);
|
||||
// Check the capacity link first.
|
||||
if (!capacity_link_.empty()) {
|
||||
int64_t last_arrival_time_us =
|
||||
delay_link_.empty() ? -1 : delay_link_.back().arrival_time_us;
|
||||
bool needs_sort = false;
|
||||
while (!capacity_link_.empty() &&
|
||||
time_now_us >= capacity_link_.front().arrival_time_us) {
|
||||
// Time to get this packet.
|
||||
PacketInfo packet = std::move(capacity_link_.front());
|
||||
capacity_link_.pop();
|
||||
|
||||
// Drop packets at an average rate of |config_.loss_percent| with
|
||||
// and average loss burst length of |config_.avg_burst_loss_length|.
|
||||
if ((bursting_ && random_.Rand<double>() < prob_loss_bursting) ||
|
||||
(!bursting_ && random_.Rand<double>() < prob_start_bursting)) {
|
||||
bursting_ = true;
|
||||
continue;
|
||||
} else {
|
||||
bursting_ = false;
|
||||
}
|
||||
|
||||
int64_t arrival_time_jitter_us = std::max(
|
||||
random_.Gaussian(config.queue_delay_ms * 1000,
|
||||
config.delay_standard_deviation_ms * 1000),
|
||||
0.0);
|
||||
|
||||
// If reordering is not allowed then adjust arrival_time_jitter
|
||||
// to make sure all packets are sent in order.
|
||||
if (!config.allow_reordering && !delay_link_.empty() &&
|
||||
packet.arrival_time_us + arrival_time_jitter_us <
|
||||
last_arrival_time_us) {
|
||||
arrival_time_jitter_us =
|
||||
last_arrival_time_us - packet.arrival_time_us;
|
||||
}
|
||||
packet.arrival_time_us += arrival_time_jitter_us;
|
||||
if (packet.arrival_time_us >= last_arrival_time_us) {
|
||||
last_arrival_time_us = packet.arrival_time_us;
|
||||
} else {
|
||||
needs_sort = true;
|
||||
}
|
||||
delay_link_.emplace_back(std::move(packet));
|
||||
}
|
||||
|
||||
if (needs_sort) {
|
||||
// Packet(s) arrived out of order, make sure list is sorted.
|
||||
std::sort(delay_link_.begin(), delay_link_.end(),
|
||||
[](const PacketInfo& p1, const PacketInfo& p2) {
|
||||
return p1.arrival_time_us < p2.arrival_time_us;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PacketDeliveryInfo> packets_to_deliver;
|
||||
// Check the extra delay queue.
|
||||
while (!delay_link_.empty() &&
|
||||
time_now_us >= delay_link_.front().arrival_time_us) {
|
||||
PacketInfo packet_info = delay_link_.front();
|
||||
packets_to_deliver.emplace_back(
|
||||
PacketDeliveryInfo(packet_info.packet, packet_info.arrival_time_us));
|
||||
delay_link_.pop_front();
|
||||
}
|
||||
return packets_to_deliver;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
80
call/simulated_network.h
Normal file
80
call/simulated_network.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
#ifndef CALL_SIMULATED_NETWORK_H_
|
||||
#define CALL_SIMULATED_NETWORK_H_
|
||||
|
||||
#include <deque>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/test/simulated_network.h"
|
||||
#include "rtc_base/criticalsection.h"
|
||||
#include "rtc_base/random.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class simulating a network link. This is a simple and naive solution just
|
||||
// faking capacity and adding an extra transport delay in addition to the
|
||||
// capacity introduced delay.
|
||||
class SimulatedNetwork : public NetworkSimulationInterface {
|
||||
public:
|
||||
using Config = NetworkSimulationInterface::SimulatedNetworkConfig;
|
||||
explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
|
||||
~SimulatedNetwork() override;
|
||||
|
||||
// Sets a new configuration. This won't affect packets already in the pipe.
|
||||
void SetConfig(const Config& config);
|
||||
void PauseTransmissionUntil(int64_t until_us);
|
||||
|
||||
// NetworkSimulationInterface
|
||||
bool EnqueuePacket(PacketInFlightInfo packet) override;
|
||||
std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
|
||||
int64_t receive_time_us) override;
|
||||
|
||||
absl::optional<int64_t> NextDeliveryTimeUs() const override;
|
||||
|
||||
private:
|
||||
struct PacketInfo {
|
||||
PacketInFlightInfo packet;
|
||||
int64_t arrival_time_us;
|
||||
};
|
||||
rtc::CriticalSection config_lock_;
|
||||
|
||||
// |process_lock| guards the data structures involved in delay and loss
|
||||
// processes, such as the packet queues.
|
||||
rtc::CriticalSection process_lock_;
|
||||
std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_lock_);
|
||||
Random random_;
|
||||
|
||||
std::deque<PacketInfo> delay_link_;
|
||||
|
||||
// Link configuration.
|
||||
Config config_ RTC_GUARDED_BY(config_lock_);
|
||||
absl::optional<int64_t> pause_transmission_until_us_
|
||||
RTC_GUARDED_BY(config_lock_);
|
||||
|
||||
// Are we currently dropping a burst of packets?
|
||||
bool bursting_;
|
||||
|
||||
// The probability to drop the packet if we are currently dropping a
|
||||
// burst of packet
|
||||
double prob_loss_bursting_ RTC_GUARDED_BY(config_lock_);
|
||||
|
||||
// The probability to drop a burst of packets.
|
||||
double prob_start_bursting_ RTC_GUARDED_BY(config_lock_);
|
||||
int64_t capacity_delay_error_bytes_ = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // CALL_SIMULATED_NETWORK_H_
|
Reference in New Issue
Block a user