Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: webrtc/test/fake_network_pipe.cc

Issue 1606183002: Allow packets to be reordered in the fake network pipe. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: uint8_t[] instead of uint8_t Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/test/fake_network_pipe.h ('k') | webrtc/test/fake_network_pipe_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/test/fake_network_pipe.h" 11 #include "webrtc/test/fake_network_pipe.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <math.h> 14 #include <math.h>
15 #include <string.h> 15 #include <string.h>
16 #include <algorithm> 16 #include <algorithm>
17 17
18 #include "webrtc/call.h" 18 #include "webrtc/call.h"
19 #include "webrtc/system_wrappers/include/clock.h" 19 #include "webrtc/system_wrappers/include/clock.h"
20 20
21 namespace webrtc { 21 namespace webrtc {
22 22
23 const double kPi = 3.14159265; 23 FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
24 24 const FakeNetworkPipe::Config& config)
25 static int GaussianRandom(int mean_delay_ms, int standard_deviation_ms) { 25 : FakeNetworkPipe(clock, config, 1) {}
26 // Creating a Normal distribution variable from two independent uniform
27 // variables based on the Box-Muller transform.
28 double uniform1 = (rand() + 1.0) / (RAND_MAX + 1.0); // NOLINT
29 double uniform2 = (rand() + 1.0) / (RAND_MAX + 1.0); // NOLINT
30 return static_cast<int>(mean_delay_ms + standard_deviation_ms *
31 sqrt(-2 * log(uniform1)) * cos(2 * kPi * uniform2));
32 }
33
34 static bool UniformLoss(int loss_percent) {
35 int outcome = rand() % 100;
36 return outcome < loss_percent;
37 }
38
39 class NetworkPacket {
40 public:
41 NetworkPacket(const uint8_t* data, size_t length, int64_t send_time,
42 int64_t arrival_time)
43 : data_(NULL),
44 data_length_(length),
45 send_time_(send_time),
46 arrival_time_(arrival_time) {
47 data_ = new uint8_t[length];
48 memcpy(data_, data, length);
49 }
50 ~NetworkPacket() {
51 delete [] data_;
52 }
53
54 uint8_t* data() const { return data_; }
55 size_t data_length() const { return data_length_; }
56 int64_t send_time() const { return send_time_; }
57 int64_t arrival_time() const { return arrival_time_; }
58 void IncrementArrivalTime(int64_t extra_delay) {
59 arrival_time_+= extra_delay;
60 }
61
62 private:
63 // The packet data.
64 uint8_t* data_;
65 // Length of data_.
66 size_t data_length_;
67 // The time the packet was sent out on the network.
68 const int64_t send_time_;
69 // The time the packet should arrive at the reciver.
70 int64_t arrival_time_;
71 };
72 26
73 FakeNetworkPipe::FakeNetworkPipe(Clock* clock, 27 FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
74 const FakeNetworkPipe::Config& config) 28 const FakeNetworkPipe::Config& config,
29 uint64_t seed)
75 : clock_(clock), 30 : clock_(clock),
76 packet_receiver_(NULL), 31 packet_receiver_(NULL),
32 random_(seed),
77 config_(config), 33 config_(config),
78 dropped_packets_(0), 34 dropped_packets_(0),
79 sent_packets_(0), 35 sent_packets_(0),
80 total_packet_delay_(0), 36 total_packet_delay_(0),
81 next_process_time_(clock_->TimeInMilliseconds()) {} 37 next_process_time_(clock_->TimeInMilliseconds()) {}
82 38
83 FakeNetworkPipe::~FakeNetworkPipe() { 39 FakeNetworkPipe::~FakeNetworkPipe() {
84 while (!capacity_link_.empty()) { 40 while (!capacity_link_.empty()) {
85 delete capacity_link_.front(); 41 delete capacity_link_.front();
86 capacity_link_.pop(); 42 capacity_link_.pop();
87 } 43 }
88 while (!delay_link_.empty()) { 44 while (!delay_link_.empty()) {
89 delete delay_link_.front(); 45 delete *delay_link_.begin();
90 delay_link_.pop(); 46 delay_link_.erase(delay_link_.begin());
91 } 47 }
92 } 48 }
93 49
94 void FakeNetworkPipe::SetReceiver(PacketReceiver* receiver) { 50 void FakeNetworkPipe::SetReceiver(PacketReceiver* receiver) {
95 packet_receiver_ = receiver; 51 packet_receiver_ = receiver;
96 } 52 }
97 53
98 void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) { 54 void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) {
99 rtc::CritScope crit(&lock_); 55 rtc::CritScope crit(&lock_);
100 config_ = config; // Shallow copy of the struct. 56 config_ = config; // Shallow copy of the struct.
(...skipping 15 matching lines...) Expand all
116 int64_t time_now = clock_->TimeInMilliseconds(); 72 int64_t time_now = clock_->TimeInMilliseconds();
117 73
118 // Delay introduced by the link capacity. 74 // Delay introduced by the link capacity.
119 int64_t capacity_delay_ms = 0; 75 int64_t capacity_delay_ms = 0;
120 if (config_.link_capacity_kbps > 0) 76 if (config_.link_capacity_kbps > 0)
121 capacity_delay_ms = data_length / (config_.link_capacity_kbps / 8); 77 capacity_delay_ms = data_length / (config_.link_capacity_kbps / 8);
122 int64_t network_start_time = time_now; 78 int64_t network_start_time = time_now;
123 79
124 // Check if there already are packets on the link and change network start 80 // Check if there already are packets on the link and change network start
125 // time if there is. 81 // time if there is.
126 if (capacity_link_.size() > 0) 82 if (!capacity_link_.empty())
127 network_start_time = capacity_link_.back()->arrival_time(); 83 network_start_time = capacity_link_.back()->arrival_time();
128 84
129 int64_t arrival_time = network_start_time + capacity_delay_ms; 85 int64_t arrival_time = network_start_time + capacity_delay_ms;
130 NetworkPacket* packet = new NetworkPacket(data, data_length, time_now, 86 NetworkPacket* packet = new NetworkPacket(data, data_length, time_now,
131 arrival_time); 87 arrival_time);
132 capacity_link_.push(packet); 88 capacity_link_.push(packet);
133 } 89 }
134 90
135 float FakeNetworkPipe::PercentageLoss() { 91 float FakeNetworkPipe::PercentageLoss() {
136 rtc::CritScope crit(&lock_); 92 rtc::CritScope crit(&lock_);
(...skipping 11 matching lines...) Expand all
148 104
149 return total_packet_delay_ / static_cast<int>(sent_packets_); 105 return total_packet_delay_ / static_cast<int>(sent_packets_);
150 } 106 }
151 107
152 void FakeNetworkPipe::Process() { 108 void FakeNetworkPipe::Process() {
153 int64_t time_now = clock_->TimeInMilliseconds(); 109 int64_t time_now = clock_->TimeInMilliseconds();
154 std::queue<NetworkPacket*> packets_to_deliver; 110 std::queue<NetworkPacket*> packets_to_deliver;
155 { 111 {
156 rtc::CritScope crit(&lock_); 112 rtc::CritScope crit(&lock_);
157 // Check the capacity link first. 113 // Check the capacity link first.
158 while (capacity_link_.size() > 0 && 114 while (!capacity_link_.empty() &&
159 time_now >= capacity_link_.front()->arrival_time()) { 115 time_now >= capacity_link_.front()->arrival_time()) {
160 // Time to get this packet. 116 // Time to get this packet.
161 NetworkPacket* packet = capacity_link_.front(); 117 NetworkPacket* packet = capacity_link_.front();
162 capacity_link_.pop(); 118 capacity_link_.pop();
163 119
164 // Packets are randomly dropped after being affected by the bottleneck. 120 // Packets are randomly dropped after being affected by the bottleneck.
165 if (UniformLoss(config_.loss_percent)) { 121 if (random_.Rand(100) < static_cast<uint32_t>(config_.loss_percent)) {
166 delete packet; 122 delete packet;
167 continue; 123 continue;
168 } 124 }
169 125
170 // Add extra delay and jitter, but make sure the arrival time is not 126 int arrival_time_jitter = random_.Gaussian(
171 // earlier than the last packet in the queue. 127 config_.queue_delay_ms, config_.delay_standard_deviation_ms);
172 int extra_delay = GaussianRandom(config_.queue_delay_ms, 128
173 config_.delay_standard_deviation_ms); 129 // If reordering is not allowed then adjust arrival_time_jitter
174 if (delay_link_.size() > 0 && 130 // to make sure all packets are sent in order.
175 packet->arrival_time() + extra_delay < 131 if (!config_.allow_reordering && !delay_link_.empty() &&
176 delay_link_.back()->arrival_time()) { 132 packet->arrival_time() + arrival_time_jitter <
177 extra_delay = delay_link_.back()->arrival_time() - 133 (*delay_link_.rbegin())->arrival_time()) {
178 packet->arrival_time(); 134 arrival_time_jitter =
135 (*delay_link_.rbegin())->arrival_time() - packet->arrival_time();
179 } 136 }
180 packet->IncrementArrivalTime(extra_delay); 137 packet->IncrementArrivalTime(arrival_time_jitter);
181 if (packet->arrival_time() < next_process_time_) 138 if (packet->arrival_time() < next_process_time_)
182 next_process_time_ = packet->arrival_time(); 139 next_process_time_ = packet->arrival_time();
183 delay_link_.push(packet); 140 delay_link_.insert(packet);
184 } 141 }
185 142
186 // Check the extra delay queue. 143 // Check the extra delay queue.
187 while (delay_link_.size() > 0 && 144 while (!delay_link_.empty() &&
188 time_now >= delay_link_.front()->arrival_time()) { 145 time_now >= (*delay_link_.begin())->arrival_time()) {
189 // Deliver this packet. 146 // Deliver this packet.
190 NetworkPacket* packet = delay_link_.front(); 147 NetworkPacket* packet = *delay_link_.begin();
191 packets_to_deliver.push(packet); 148 packets_to_deliver.push(packet);
192 delay_link_.pop(); 149 delay_link_.erase(delay_link_.begin());
193 // |time_now| might be later than when the packet should have arrived, due 150 // |time_now| might be later than when the packet should have arrived, due
194 // to NetworkProcess being called too late. For stats, use the time it 151 // to NetworkProcess being called too late. For stats, use the time it
195 // should have been on the link. 152 // should have been on the link.
196 total_packet_delay_ += packet->arrival_time() - packet->send_time(); 153 total_packet_delay_ += packet->arrival_time() - packet->send_time();
197 } 154 }
198 sent_packets_ += packets_to_deliver.size(); 155 sent_packets_ += packets_to_deliver.size();
199 } 156 }
200 while (!packets_to_deliver.empty()) { 157 while (!packets_to_deliver.empty()) {
201 NetworkPacket* packet = packets_to_deliver.front(); 158 NetworkPacket* packet = packets_to_deliver.front();
202 packets_to_deliver.pop(); 159 packets_to_deliver.pop();
203 packet_receiver_->DeliverPacket(MediaType::ANY, packet->data(), 160 packet_receiver_->DeliverPacket(MediaType::ANY, packet->data(),
204 packet->data_length(), PacketTime()); 161 packet->data_length(), PacketTime());
205 delete packet; 162 delete packet;
206 } 163 }
207 } 164 }
208 165
209 int64_t FakeNetworkPipe::TimeUntilNextProcess() const { 166 int64_t FakeNetworkPipe::TimeUntilNextProcess() const {
210 rtc::CritScope crit(&lock_); 167 rtc::CritScope crit(&lock_);
211 const int64_t kDefaultProcessIntervalMs = 30; 168 const int64_t kDefaultProcessIntervalMs = 30;
212 if (capacity_link_.size() == 0 || delay_link_.size() == 0) 169 if (capacity_link_.empty() || delay_link_.empty())
213 return kDefaultProcessIntervalMs; 170 return kDefaultProcessIntervalMs;
214 return std::max<int64_t>(next_process_time_ - clock_->TimeInMilliseconds(), 171 return std::max<int64_t>(next_process_time_ - clock_->TimeInMilliseconds(),
215 0); 172 0);
216 } 173 }
217 174
218 } // namespace webrtc 175 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/test/fake_network_pipe.h ('k') | webrtc/test/fake_network_pipe_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698