OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "media/cast/test/utility/udp_proxy.h" |
| 6 |
5 #include <math.h> | 7 #include <math.h> |
6 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <utility> |
7 #include <vector> | 10 #include <vector> |
8 | 11 |
9 #include "media/cast/test/utility/udp_proxy.h" | |
10 | |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/macros.h" | 13 #include "base/macros.h" |
13 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
14 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
15 #include "base/thread_task_runner_handle.h" | 16 #include "base/thread_task_runner_handle.h" |
16 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
17 #include "base/time/default_tick_clock.h" | 18 #include "base/time/default_tick_clock.h" |
18 #include "net/base/io_buffer.h" | 19 #include "net/base/io_buffer.h" |
19 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
20 #include "net/udp/udp_server_socket.h" | 21 #include "net/udp/udp_server_socket.h" |
(...skipping 10 matching lines...) Expand all Loading... |
31 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 32 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
32 base::TickClock* clock) { | 33 base::TickClock* clock) { |
33 task_runner_ = task_runner; | 34 task_runner_ = task_runner; |
34 clock_ = clock; | 35 clock_ = clock; |
35 if (pipe_) { | 36 if (pipe_) { |
36 pipe_->InitOnIOThread(task_runner, clock); | 37 pipe_->InitOnIOThread(task_runner, clock); |
37 } | 38 } |
38 } | 39 } |
39 void PacketPipe::AppendToPipe(scoped_ptr<PacketPipe> pipe) { | 40 void PacketPipe::AppendToPipe(scoped_ptr<PacketPipe> pipe) { |
40 if (pipe_) { | 41 if (pipe_) { |
41 pipe_->AppendToPipe(pipe.Pass()); | 42 pipe_->AppendToPipe(std::move(pipe)); |
42 } else { | 43 } else { |
43 pipe_ = pipe.Pass(); | 44 pipe_ = std::move(pipe); |
44 } | 45 } |
45 } | 46 } |
46 | 47 |
47 // Roughly emulates a buffer inside a device. | 48 // Roughly emulates a buffer inside a device. |
48 // If the buffer is full, packets are dropped. | 49 // If the buffer is full, packets are dropped. |
49 // Packets are output at a maximum bandwidth. | 50 // Packets are output at a maximum bandwidth. |
50 class Buffer : public PacketPipe { | 51 class Buffer : public PacketPipe { |
51 public: | 52 public: |
52 Buffer(size_t buffer_size, double max_megabits_per_second) | 53 Buffer(size_t buffer_size, double max_megabits_per_second) |
53 : buffer_size_(0), | 54 : buffer_size_(0), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 if (bytes_to_send < static_cast<int64_t>(buffer_.front()->size())) { | 88 if (bytes_to_send < static_cast<int64_t>(buffer_.front()->size())) { |
88 bytes_to_send = buffer_.front()->size(); | 89 bytes_to_send = buffer_.front()->size(); |
89 } | 90 } |
90 while (!buffer_.empty() && | 91 while (!buffer_.empty() && |
91 static_cast<int64_t>(buffer_.front()->size()) <= bytes_to_send) { | 92 static_cast<int64_t>(buffer_.front()->size()) <= bytes_to_send) { |
92 CHECK(!buffer_.empty()); | 93 CHECK(!buffer_.empty()); |
93 scoped_ptr<Packet> packet(buffer_.front().release()); | 94 scoped_ptr<Packet> packet(buffer_.front().release()); |
94 bytes_to_send -= packet->size(); | 95 bytes_to_send -= packet->size(); |
95 buffer_size_ -= packet->size(); | 96 buffer_size_ -= packet->size(); |
96 buffer_.pop_front(); | 97 buffer_.pop_front(); |
97 pipe_->Send(packet.Pass()); | 98 pipe_->Send(std::move(packet)); |
98 } | 99 } |
99 if (!buffer_.empty()) { | 100 if (!buffer_.empty()) { |
100 Schedule(); | 101 Schedule(); |
101 } | 102 } |
102 } | 103 } |
103 | 104 |
104 std::deque<linked_ptr<Packet> > buffer_; | 105 std::deque<linked_ptr<Packet> > buffer_; |
105 base::TimeTicks last_schedule_; | 106 base::TimeTicks last_schedule_; |
106 size_t buffer_size_; | 107 size_t buffer_size_; |
107 size_t max_buffer_size_; | 108 size_t max_buffer_size_; |
108 double max_megabits_per_second_; // megabits per second | 109 double max_megabits_per_second_; // megabits per second |
109 base::WeakPtrFactory<Buffer> weak_factory_; | 110 base::WeakPtrFactory<Buffer> weak_factory_; |
110 }; | 111 }; |
111 | 112 |
112 scoped_ptr<PacketPipe> NewBuffer(size_t buffer_size, double bandwidth) { | 113 scoped_ptr<PacketPipe> NewBuffer(size_t buffer_size, double bandwidth) { |
113 return scoped_ptr<PacketPipe>(new Buffer(buffer_size, bandwidth)).Pass(); | 114 return scoped_ptr<PacketPipe>(new Buffer(buffer_size, bandwidth)); |
114 } | 115 } |
115 | 116 |
116 class RandomDrop : public PacketPipe { | 117 class RandomDrop : public PacketPipe { |
117 public: | 118 public: |
118 RandomDrop(double drop_fraction) | 119 RandomDrop(double drop_fraction) |
119 : drop_fraction_(static_cast<int>(drop_fraction * RAND_MAX)) {} | 120 : drop_fraction_(static_cast<int>(drop_fraction * RAND_MAX)) {} |
120 | 121 |
121 void Send(scoped_ptr<Packet> packet) final { | 122 void Send(scoped_ptr<Packet> packet) final { |
122 if (rand() > drop_fraction_) { | 123 if (rand() > drop_fraction_) { |
123 pipe_->Send(packet.Pass()); | 124 pipe_->Send(std::move(packet)); |
124 } | 125 } |
125 } | 126 } |
126 | 127 |
127 private: | 128 private: |
128 int drop_fraction_; | 129 int drop_fraction_; |
129 }; | 130 }; |
130 | 131 |
131 scoped_ptr<PacketPipe> NewRandomDrop(double drop_fraction) { | 132 scoped_ptr<PacketPipe> NewRandomDrop(double drop_fraction) { |
132 return scoped_ptr<PacketPipe>(new RandomDrop(drop_fraction)).Pass(); | 133 return scoped_ptr<PacketPipe>(new RandomDrop(drop_fraction)); |
133 } | 134 } |
134 | 135 |
135 class SimpleDelayBase : public PacketPipe { | 136 class SimpleDelayBase : public PacketPipe { |
136 public: | 137 public: |
137 SimpleDelayBase() : weak_factory_(this) {} | 138 SimpleDelayBase() : weak_factory_(this) {} |
138 ~SimpleDelayBase() override {} | 139 ~SimpleDelayBase() override {} |
139 | 140 |
140 void Send(scoped_ptr<Packet> packet) override { | 141 void Send(scoped_ptr<Packet> packet) override { |
141 double seconds = GetDelay(); | 142 double seconds = GetDelay(); |
142 task_runner_->PostDelayedTask( | 143 task_runner_->PostDelayedTask( |
143 FROM_HERE, | 144 FROM_HERE, |
144 base::Bind(&SimpleDelayBase::SendInternal, weak_factory_.GetWeakPtr(), | 145 base::Bind(&SimpleDelayBase::SendInternal, weak_factory_.GetWeakPtr(), |
145 base::Passed(&packet)), | 146 base::Passed(&packet)), |
146 base::TimeDelta::FromMicroseconds(static_cast<int64_t>(seconds * 1E6))); | 147 base::TimeDelta::FromMicroseconds(static_cast<int64_t>(seconds * 1E6))); |
147 } | 148 } |
148 protected: | 149 protected: |
149 virtual double GetDelay() = 0; | 150 virtual double GetDelay() = 0; |
150 | 151 |
151 private: | 152 private: |
152 virtual void SendInternal(scoped_ptr<Packet> packet) { | 153 virtual void SendInternal(scoped_ptr<Packet> packet) { |
153 pipe_->Send(packet.Pass()); | 154 pipe_->Send(std::move(packet)); |
154 } | 155 } |
155 | 156 |
156 base::WeakPtrFactory<SimpleDelayBase> weak_factory_; | 157 base::WeakPtrFactory<SimpleDelayBase> weak_factory_; |
157 }; | 158 }; |
158 | 159 |
159 class ConstantDelay : public SimpleDelayBase { | 160 class ConstantDelay : public SimpleDelayBase { |
160 public: | 161 public: |
161 ConstantDelay(double delay_seconds) : delay_seconds_(delay_seconds) {} | 162 ConstantDelay(double delay_seconds) : delay_seconds_(delay_seconds) {} |
162 double GetDelay() final { return delay_seconds_; } | 163 double GetDelay() final { return delay_seconds_; } |
163 | 164 |
164 private: | 165 private: |
165 double delay_seconds_; | 166 double delay_seconds_; |
166 }; | 167 }; |
167 | 168 |
168 scoped_ptr<PacketPipe> NewConstantDelay(double delay_seconds) { | 169 scoped_ptr<PacketPipe> NewConstantDelay(double delay_seconds) { |
169 return scoped_ptr<PacketPipe>(new ConstantDelay(delay_seconds)).Pass(); | 170 return scoped_ptr<PacketPipe>(new ConstantDelay(delay_seconds)); |
170 } | 171 } |
171 | 172 |
172 class RandomUnsortedDelay : public SimpleDelayBase { | 173 class RandomUnsortedDelay : public SimpleDelayBase { |
173 public: | 174 public: |
174 RandomUnsortedDelay(double random_delay) : random_delay_(random_delay) {} | 175 RandomUnsortedDelay(double random_delay) : random_delay_(random_delay) {} |
175 | 176 |
176 double GetDelay() override { return random_delay_ * base::RandDouble(); } | 177 double GetDelay() override { return random_delay_ * base::RandDouble(); } |
177 | 178 |
178 private: | 179 private: |
179 double random_delay_; | 180 double random_delay_; |
180 }; | 181 }; |
181 | 182 |
182 scoped_ptr<PacketPipe> NewRandomUnsortedDelay(double random_delay) { | 183 scoped_ptr<PacketPipe> NewRandomUnsortedDelay(double random_delay) { |
183 return scoped_ptr<PacketPipe>(new RandomUnsortedDelay(random_delay)).Pass(); | 184 return scoped_ptr<PacketPipe>(new RandomUnsortedDelay(random_delay)); |
184 } | 185 } |
185 | 186 |
186 class DuplicateAndDelay : public RandomUnsortedDelay { | 187 class DuplicateAndDelay : public RandomUnsortedDelay { |
187 public: | 188 public: |
188 DuplicateAndDelay(double delay_min, | 189 DuplicateAndDelay(double delay_min, |
189 double random_delay) : | 190 double random_delay) : |
190 RandomUnsortedDelay(random_delay), | 191 RandomUnsortedDelay(random_delay), |
191 delay_min_(delay_min) { | 192 delay_min_(delay_min) { |
192 } | 193 } |
193 void Send(scoped_ptr<Packet> packet) final { | 194 void Send(scoped_ptr<Packet> packet) final { |
194 pipe_->Send(scoped_ptr<Packet>(new Packet(*packet.get()))); | 195 pipe_->Send(scoped_ptr<Packet>(new Packet(*packet.get()))); |
195 RandomUnsortedDelay::Send(packet.Pass()); | 196 RandomUnsortedDelay::Send(std::move(packet)); |
196 } | 197 } |
197 double GetDelay() final { | 198 double GetDelay() final { |
198 return RandomUnsortedDelay::GetDelay() + delay_min_; | 199 return RandomUnsortedDelay::GetDelay() + delay_min_; |
199 } | 200 } |
200 private: | 201 private: |
201 double delay_min_; | 202 double delay_min_; |
202 }; | 203 }; |
203 | 204 |
204 scoped_ptr<PacketPipe> NewDuplicateAndDelay(double delay_min, | 205 scoped_ptr<PacketPipe> NewDuplicateAndDelay(double delay_min, |
205 double random_delay) { | 206 double random_delay) { |
206 return scoped_ptr<PacketPipe>( | 207 return scoped_ptr<PacketPipe>(new DuplicateAndDelay(delay_min, random_delay)); |
207 new DuplicateAndDelay(delay_min, random_delay)).Pass(); | |
208 } | 208 } |
209 | 209 |
210 class RandomSortedDelay : public PacketPipe { | 210 class RandomSortedDelay : public PacketPipe { |
211 public: | 211 public: |
212 RandomSortedDelay(double random_delay, | 212 RandomSortedDelay(double random_delay, |
213 double extra_delay, | 213 double extra_delay, |
214 double seconds_between_extra_delay) | 214 double seconds_between_extra_delay) |
215 : random_delay_(random_delay), | 215 : random_delay_(random_delay), |
216 extra_delay_(extra_delay), | 216 extra_delay_(extra_delay), |
217 seconds_between_extra_delay_(seconds_between_extra_delay), | 217 seconds_between_extra_delay_(seconds_between_extra_delay), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 // An extra delay just happened, wait up to seconds_between_extra_delay_*2 | 255 // An extra delay just happened, wait up to seconds_between_extra_delay_*2 |
256 // before scheduling another one to make the average equal to | 256 // before scheduling another one to make the average equal to |
257 // seconds_between_extra_delay_. | 257 // seconds_between_extra_delay_. |
258 ScheduleExtraDelay(2.0); | 258 ScheduleExtraDelay(2.0); |
259 } | 259 } |
260 | 260 |
261 void ProcessBuffer() { | 261 void ProcessBuffer() { |
262 base::TimeTicks now = clock_->NowTicks(); | 262 base::TimeTicks now = clock_->NowTicks(); |
263 while (!buffer_.empty() && next_send_ <= now) { | 263 while (!buffer_.empty() && next_send_ <= now) { |
264 scoped_ptr<Packet> packet(buffer_.front().release()); | 264 scoped_ptr<Packet> packet(buffer_.front().release()); |
265 pipe_->Send(packet.Pass()); | 265 pipe_->Send(std::move(packet)); |
266 buffer_.pop_front(); | 266 buffer_.pop_front(); |
267 | 267 |
268 next_send_ += base::TimeDelta::FromSecondsD( | 268 next_send_ += base::TimeDelta::FromSecondsD( |
269 base::RandDouble() * random_delay_); | 269 base::RandDouble() * random_delay_); |
270 } | 270 } |
271 | 271 |
272 if (!buffer_.empty()) { | 272 if (!buffer_.empty()) { |
273 task_runner_->PostDelayedTask( | 273 task_runner_->PostDelayedTask( |
274 FROM_HERE, | 274 FROM_HERE, |
275 base::Bind(&RandomSortedDelay::ProcessBuffer, | 275 base::Bind(&RandomSortedDelay::ProcessBuffer, |
276 weak_factory_.GetWeakPtr()), | 276 weak_factory_.GetWeakPtr()), |
277 next_send_ - now); | 277 next_send_ - now); |
278 } | 278 } |
279 } | 279 } |
280 | 280 |
281 base::TimeTicks block_until_; | 281 base::TimeTicks block_until_; |
282 std::deque<linked_ptr<Packet> > buffer_; | 282 std::deque<linked_ptr<Packet> > buffer_; |
283 double random_delay_; | 283 double random_delay_; |
284 double extra_delay_; | 284 double extra_delay_; |
285 double seconds_between_extra_delay_; | 285 double seconds_between_extra_delay_; |
286 base::TimeTicks next_send_; | 286 base::TimeTicks next_send_; |
287 base::WeakPtrFactory<RandomSortedDelay> weak_factory_; | 287 base::WeakPtrFactory<RandomSortedDelay> weak_factory_; |
288 }; | 288 }; |
289 | 289 |
290 scoped_ptr<PacketPipe> NewRandomSortedDelay( | 290 scoped_ptr<PacketPipe> NewRandomSortedDelay( |
291 double random_delay, | 291 double random_delay, |
292 double extra_delay, | 292 double extra_delay, |
293 double seconds_between_extra_delay) { | 293 double seconds_between_extra_delay) { |
294 return scoped_ptr<PacketPipe>( | 294 return scoped_ptr<PacketPipe>(new RandomSortedDelay( |
295 new RandomSortedDelay( | 295 random_delay, extra_delay, seconds_between_extra_delay)); |
296 random_delay, extra_delay, seconds_between_extra_delay)) | |
297 .Pass(); | |
298 } | 296 } |
299 | 297 |
300 class NetworkGlitchPipe : public PacketPipe { | 298 class NetworkGlitchPipe : public PacketPipe { |
301 public: | 299 public: |
302 NetworkGlitchPipe(double average_work_time, double average_outage_time) | 300 NetworkGlitchPipe(double average_work_time, double average_outage_time) |
303 : works_(false), | 301 : works_(false), |
304 max_work_time_(average_work_time * 2), | 302 max_work_time_(average_work_time * 2), |
305 max_outage_time_(average_outage_time * 2), | 303 max_outage_time_(average_outage_time * 2), |
306 weak_factory_(this) {} | 304 weak_factory_(this) {} |
307 | 305 |
308 void InitOnIOThread( | 306 void InitOnIOThread( |
309 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 307 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
310 base::TickClock* clock) final { | 308 base::TickClock* clock) final { |
311 PacketPipe::InitOnIOThread(task_runner, clock); | 309 PacketPipe::InitOnIOThread(task_runner, clock); |
312 Flip(); | 310 Flip(); |
313 } | 311 } |
314 | 312 |
315 void Send(scoped_ptr<Packet> packet) final { | 313 void Send(scoped_ptr<Packet> packet) final { |
316 if (works_) { | 314 if (works_) { |
317 pipe_->Send(packet.Pass()); | 315 pipe_->Send(std::move(packet)); |
318 } | 316 } |
319 } | 317 } |
320 | 318 |
321 private: | 319 private: |
322 void Flip() { | 320 void Flip() { |
323 works_ = !works_; | 321 works_ = !works_; |
324 double seconds = base::RandDouble() * | 322 double seconds = base::RandDouble() * |
325 (works_ ? max_work_time_ : max_outage_time_); | 323 (works_ ? max_work_time_ : max_outage_time_); |
326 int64_t microseconds = static_cast<int64_t>(seconds * 1E6); | 324 int64_t microseconds = static_cast<int64_t>(seconds * 1E6); |
327 task_runner_->PostDelayedTask( | 325 task_runner_->PostDelayedTask( |
328 FROM_HERE, | 326 FROM_HERE, |
329 base::Bind(&NetworkGlitchPipe::Flip, weak_factory_.GetWeakPtr()), | 327 base::Bind(&NetworkGlitchPipe::Flip, weak_factory_.GetWeakPtr()), |
330 base::TimeDelta::FromMicroseconds(microseconds)); | 328 base::TimeDelta::FromMicroseconds(microseconds)); |
331 } | 329 } |
332 | 330 |
333 bool works_; | 331 bool works_; |
334 double max_work_time_; | 332 double max_work_time_; |
335 double max_outage_time_; | 333 double max_outage_time_; |
336 base::WeakPtrFactory<NetworkGlitchPipe> weak_factory_; | 334 base::WeakPtrFactory<NetworkGlitchPipe> weak_factory_; |
337 }; | 335 }; |
338 | 336 |
339 scoped_ptr<PacketPipe> NewNetworkGlitchPipe(double average_work_time, | 337 scoped_ptr<PacketPipe> NewNetworkGlitchPipe(double average_work_time, |
340 double average_outage_time) { | 338 double average_outage_time) { |
341 return scoped_ptr<PacketPipe>( | 339 return scoped_ptr<PacketPipe>( |
342 new NetworkGlitchPipe(average_work_time, average_outage_time)) | 340 new NetworkGlitchPipe(average_work_time, average_outage_time)); |
343 .Pass(); | |
344 } | 341 } |
345 | 342 |
346 | 343 |
347 // Internal buffer object for a client of the IPP model. | 344 // Internal buffer object for a client of the IPP model. |
348 class InterruptedPoissonProcess::InternalBuffer : public PacketPipe { | 345 class InterruptedPoissonProcess::InternalBuffer : public PacketPipe { |
349 public: | 346 public: |
350 InternalBuffer(base::WeakPtr<InterruptedPoissonProcess> ipp, | 347 InternalBuffer(base::WeakPtr<InterruptedPoissonProcess> ipp, |
351 size_t size) | 348 size_t size) |
352 : ipp_(ipp), | 349 : ipp_(ipp), |
353 stored_size_(0), | 350 stored_size_(0), |
(...skipping 19 matching lines...) Expand all Loading... |
373 if (ipp_) | 370 if (ipp_) |
374 ipp_->InitOnIOThread(task_runner, clock); | 371 ipp_->InitOnIOThread(task_runner, clock); |
375 PacketPipe::InitOnIOThread(task_runner, clock); | 372 PacketPipe::InitOnIOThread(task_runner, clock); |
376 } | 373 } |
377 | 374 |
378 void SendOnePacket() { | 375 void SendOnePacket() { |
379 scoped_ptr<Packet> packet(buffer_.front().release()); | 376 scoped_ptr<Packet> packet(buffer_.front().release()); |
380 stored_size_ -= packet->size(); | 377 stored_size_ -= packet->size(); |
381 buffer_.pop_front(); | 378 buffer_.pop_front(); |
382 buffer_time_.pop_front(); | 379 buffer_time_.pop_front(); |
383 pipe_->Send(packet.Pass()); | 380 pipe_->Send(std::move(packet)); |
384 DCHECK(buffer_.size() == buffer_time_.size()); | 381 DCHECK(buffer_.size() == buffer_time_.size()); |
385 } | 382 } |
386 | 383 |
387 bool Empty() const { | 384 bool Empty() const { |
388 return buffer_.empty(); | 385 return buffer_.empty(); |
389 } | 386 } |
390 | 387 |
391 base::TimeTicks FirstPacketTime() const { | 388 base::TimeTicks FirstPacketTime() const { |
392 DCHECK(!buffer_time_.empty()); | 389 DCHECK(!buffer_time_.empty()); |
393 return buffer_time_.front(); | 390 return buffer_time_.front(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 clock_ = clock; | 437 clock_ = clock; |
441 UpdateRates(); | 438 UpdateRates(); |
442 SwitchOn(); | 439 SwitchOn(); |
443 SendPacket(); | 440 SendPacket(); |
444 } | 441 } |
445 | 442 |
446 scoped_ptr<PacketPipe> InterruptedPoissonProcess::NewBuffer(size_t size) { | 443 scoped_ptr<PacketPipe> InterruptedPoissonProcess::NewBuffer(size_t size) { |
447 scoped_ptr<InternalBuffer> buffer( | 444 scoped_ptr<InternalBuffer> buffer( |
448 new InternalBuffer(weak_factory_.GetWeakPtr(), size)); | 445 new InternalBuffer(weak_factory_.GetWeakPtr(), size)); |
449 send_buffers_.push_back(buffer->GetWeakPtr()); | 446 send_buffers_.push_back(buffer->GetWeakPtr()); |
450 return buffer.Pass(); | 447 return std::move(buffer); |
451 } | 448 } |
452 | 449 |
453 base::TimeDelta InterruptedPoissonProcess::NextEvent(double rate) { | 450 base::TimeDelta InterruptedPoissonProcess::NextEvent(double rate) { |
454 // Rate is per milliseconds. | 451 // Rate is per milliseconds. |
455 // The time until next event is exponentially distributed to the | 452 // The time until next event is exponentially distributed to the |
456 // inverse of |rate|. | 453 // inverse of |rate|. |
457 return base::TimeDelta::FromMillisecondsD( | 454 return base::TimeDelta::FromMillisecondsD( |
458 fabs(-log(1.0 - RandDouble()) / rate)); | 455 fabs(-log(1.0 - RandDouble()) / rate)); |
459 } | 456 } |
460 | 457 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 void AppendToPipe(scoped_ptr<PacketPipe> pipe) final { NOTREACHED(); } | 549 void AppendToPipe(scoped_ptr<PacketPipe> pipe) final { NOTREACHED(); } |
553 | 550 |
554 private: | 551 private: |
555 UDPProxyImpl* udp_proxy_; | 552 UDPProxyImpl* udp_proxy_; |
556 const net::IPEndPoint* destination_; // not owned | 553 const net::IPEndPoint* destination_; // not owned |
557 }; | 554 }; |
558 | 555 |
559 namespace { | 556 namespace { |
560 void BuildPipe(scoped_ptr<PacketPipe>* pipe, PacketPipe* next) { | 557 void BuildPipe(scoped_ptr<PacketPipe>* pipe, PacketPipe* next) { |
561 if (*pipe) { | 558 if (*pipe) { |
562 (*pipe)->AppendToPipe(scoped_ptr<PacketPipe>(next).Pass()); | 559 (*pipe)->AppendToPipe(scoped_ptr<PacketPipe>(next)); |
563 } else { | 560 } else { |
564 pipe->reset(next); | 561 pipe->reset(next); |
565 } | 562 } |
566 } | 563 } |
567 } // namespace | 564 } // namespace |
568 | 565 |
569 scoped_ptr<PacketPipe> GoodNetwork() { | 566 scoped_ptr<PacketPipe> GoodNetwork() { |
570 // This represents the buffer on the sender. | 567 // This represents the buffer on the sender. |
571 scoped_ptr<PacketPipe> pipe; | 568 scoped_ptr<PacketPipe> pipe; |
572 BuildPipe(&pipe, new Buffer(2 << 20, 50)); | 569 BuildPipe(&pipe, new Buffer(2 << 20, 50)); |
573 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 570 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
574 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 2E-3, 3)); | 571 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 2E-3, 3)); |
575 // This represents the buffer on the receiving device. | 572 // This represents the buffer on the receiving device. |
576 BuildPipe(&pipe, new Buffer(2 << 20, 50)); | 573 BuildPipe(&pipe, new Buffer(2 << 20, 50)); |
577 return pipe.Pass(); | 574 return pipe; |
578 } | 575 } |
579 | 576 |
580 scoped_ptr<PacketPipe> WifiNetwork() { | 577 scoped_ptr<PacketPipe> WifiNetwork() { |
581 // This represents the buffer on the sender. | 578 // This represents the buffer on the sender. |
582 scoped_ptr<PacketPipe> pipe; | 579 scoped_ptr<PacketPipe> pipe; |
583 BuildPipe(&pipe, new Buffer(256 << 10, 20)); | 580 BuildPipe(&pipe, new Buffer(256 << 10, 20)); |
584 BuildPipe(&pipe, new RandomDrop(0.005)); | 581 BuildPipe(&pipe, new RandomDrop(0.005)); |
585 // This represents the buffer on the router. | 582 // This represents the buffer on the router. |
586 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 583 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
587 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); | 584 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); |
588 BuildPipe(&pipe, new Buffer(256 << 10, 20)); | 585 BuildPipe(&pipe, new Buffer(256 << 10, 20)); |
589 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 586 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
590 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); | 587 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); |
591 BuildPipe(&pipe, new RandomDrop(0.005)); | 588 BuildPipe(&pipe, new RandomDrop(0.005)); |
592 // This represents the buffer on the receiving device. | 589 // This represents the buffer on the receiving device. |
593 BuildPipe(&pipe, new Buffer(256 << 10, 20)); | 590 BuildPipe(&pipe, new Buffer(256 << 10, 20)); |
594 return pipe.Pass(); | 591 return pipe; |
595 } | 592 } |
596 | 593 |
597 scoped_ptr<PacketPipe> BadNetwork() { | 594 scoped_ptr<PacketPipe> BadNetwork() { |
598 scoped_ptr<PacketPipe> pipe; | 595 scoped_ptr<PacketPipe> pipe; |
599 // This represents the buffer on the sender. | 596 // This represents the buffer on the sender. |
600 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s | 597 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s |
601 BuildPipe(&pipe, new RandomDrop(0.05)); // 5% packet drop | 598 BuildPipe(&pipe, new RandomDrop(0.05)); // 5% packet drop |
602 BuildPipe(&pipe, new RandomSortedDelay(2E-3, 20E-3, 1)); | 599 BuildPipe(&pipe, new RandomSortedDelay(2E-3, 20E-3, 1)); |
603 // This represents the buffer on the router. | 600 // This represents the buffer on the router. |
604 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 4mbit/s | 601 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 4mbit/s |
605 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 602 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
606 // Random 40ms every other second | 603 // Random 40ms every other second |
607 // BuildPipe(&pipe, new NetworkGlitchPipe(2, 40E-1)); | 604 // BuildPipe(&pipe, new NetworkGlitchPipe(2, 40E-1)); |
608 BuildPipe(&pipe, new RandomUnsortedDelay(5E-3)); | 605 BuildPipe(&pipe, new RandomUnsortedDelay(5E-3)); |
609 // This represents the buffer on the receiving device. | 606 // This represents the buffer on the receiving device. |
610 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s | 607 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s |
611 return pipe.Pass(); | 608 return pipe; |
612 } | 609 } |
613 | 610 |
614 | 611 |
615 scoped_ptr<PacketPipe> EvilNetwork() { | 612 scoped_ptr<PacketPipe> EvilNetwork() { |
616 // This represents the buffer on the sender. | 613 // This represents the buffer on the sender. |
617 scoped_ptr<PacketPipe> pipe; | 614 scoped_ptr<PacketPipe> pipe; |
618 BuildPipe(&pipe, new Buffer(4 << 10, 5)); // 4 kb buf, 2mbit/s | 615 BuildPipe(&pipe, new Buffer(4 << 10, 5)); // 4 kb buf, 2mbit/s |
619 // This represents the buffer on the router. | 616 // This represents the buffer on the router. |
620 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop | 617 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop |
621 BuildPipe(&pipe, new RandomSortedDelay(20E-3, 60E-3, 1)); | 618 BuildPipe(&pipe, new RandomSortedDelay(20E-3, 60E-3, 1)); |
622 BuildPipe(&pipe, new Buffer(4 << 10, 2)); // 4 kb buf, 2mbit/s | 619 BuildPipe(&pipe, new Buffer(4 << 10, 2)); // 4 kb buf, 2mbit/s |
623 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop | 620 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop |
624 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 621 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
625 BuildPipe(&pipe, new NetworkGlitchPipe(2.0, 0.3)); | 622 BuildPipe(&pipe, new NetworkGlitchPipe(2.0, 0.3)); |
626 BuildPipe(&pipe, new RandomUnsortedDelay(20E-3)); | 623 BuildPipe(&pipe, new RandomUnsortedDelay(20E-3)); |
627 // This represents the buffer on the receiving device. | 624 // This represents the buffer on the receiving device. |
628 BuildPipe(&pipe, new Buffer(4 << 10, 2)); // 4 kb buf, 2mbit/s | 625 BuildPipe(&pipe, new Buffer(4 << 10, 2)); // 4 kb buf, 2mbit/s |
629 return pipe.Pass(); | 626 return pipe; |
630 } | 627 } |
631 | 628 |
632 scoped_ptr<InterruptedPoissonProcess> DefaultInterruptedPoissonProcess() { | 629 scoped_ptr<InterruptedPoissonProcess> DefaultInterruptedPoissonProcess() { |
633 // The following values are taken from a session reported from a user. | 630 // The following values are taken from a session reported from a user. |
634 // They are experimentally tested to demonstrate challenging network | 631 // They are experimentally tested to demonstrate challenging network |
635 // conditions. The average bitrate is about 2mbits/s. | 632 // conditions. The average bitrate is about 2mbits/s. |
636 | 633 |
637 // Each element in this vector is the average number of packets sent | 634 // Each element in this vector is the average number of packets sent |
638 // per millisecond. The average changes and rotates every second. | 635 // per millisecond. The average changes and rotates every second. |
639 std::vector<double> average_rates; | 636 std::vector<double> average_rates; |
(...skipping 13 matching lines...) Expand all Loading... |
653 average_rates.push_back(0.980); | 650 average_rates.push_back(0.980); |
654 average_rates.push_back(0.781); | 651 average_rates.push_back(0.781); |
655 average_rates.push_back(0.463); | 652 average_rates.push_back(0.463); |
656 | 653 |
657 const double burstiness = 0.609; | 654 const double burstiness = 0.609; |
658 const double variance = 4.1; | 655 const double variance = 4.1; |
659 | 656 |
660 scoped_ptr<InterruptedPoissonProcess> ipp( | 657 scoped_ptr<InterruptedPoissonProcess> ipp( |
661 new InterruptedPoissonProcess( | 658 new InterruptedPoissonProcess( |
662 average_rates, burstiness, variance, 0)); | 659 average_rates, burstiness, variance, 0)); |
663 return ipp.Pass(); | 660 return ipp; |
664 } | 661 } |
665 | 662 |
666 class UDPProxyImpl : public UDPProxy { | 663 class UDPProxyImpl : public UDPProxy { |
667 public: | 664 public: |
668 UDPProxyImpl(const net::IPEndPoint& local_port, | 665 UDPProxyImpl(const net::IPEndPoint& local_port, |
669 const net::IPEndPoint& destination, | 666 const net::IPEndPoint& destination, |
670 scoped_ptr<PacketPipe> to_dest_pipe, | 667 scoped_ptr<PacketPipe> to_dest_pipe, |
671 scoped_ptr<PacketPipe> from_dest_pipe, | 668 scoped_ptr<PacketPipe> from_dest_pipe, |
672 net::NetLog* net_log) | 669 net::NetLog* net_log) |
673 : local_port_(local_port), | 670 : local_port_(local_port), |
674 destination_(destination), | 671 destination_(destination), |
675 destination_is_mutable_(destination.address().empty()), | 672 destination_is_mutable_(destination.address().empty()), |
676 proxy_thread_("media::cast::test::UdpProxy Thread"), | 673 proxy_thread_("media::cast::test::UdpProxy Thread"), |
677 to_dest_pipe_(to_dest_pipe.Pass()), | 674 to_dest_pipe_(std::move(to_dest_pipe)), |
678 from_dest_pipe_(from_dest_pipe.Pass()), | 675 from_dest_pipe_(std::move(from_dest_pipe)), |
679 blocked_(false), | 676 blocked_(false), |
680 weak_factory_(this) { | 677 weak_factory_(this) { |
681 proxy_thread_.StartWithOptions( | 678 proxy_thread_.StartWithOptions( |
682 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 679 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
683 base::WaitableEvent start_event(false, false); | 680 base::WaitableEvent start_event(false, false); |
684 proxy_thread_.task_runner()->PostTask( | 681 proxy_thread_.task_runner()->PostTask( |
685 FROM_HERE, | 682 FROM_HERE, |
686 base::Bind(&UDPProxyImpl::Start, | 683 base::Bind(&UDPProxyImpl::Start, |
687 base::Unretained(this), | 684 base::Unretained(this), |
688 base::Unretained(&start_event), | 685 base::Unretained(&start_event), |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 return; | 768 return; |
772 } | 769 } |
773 packet_->resize(len); | 770 packet_->resize(len); |
774 if (destination_is_mutable_ && set_destination_next_ && | 771 if (destination_is_mutable_ && set_destination_next_ && |
775 !(recv_address_ == return_address_) && | 772 !(recv_address_ == return_address_) && |
776 !(recv_address_ == destination_)) { | 773 !(recv_address_ == destination_)) { |
777 destination_ = recv_address_; | 774 destination_ = recv_address_; |
778 } | 775 } |
779 if (recv_address_ == destination_) { | 776 if (recv_address_ == destination_) { |
780 set_destination_next_ = false; | 777 set_destination_next_ = false; |
781 from_dest_pipe_->Send(packet_.Pass()); | 778 from_dest_pipe_->Send(std::move(packet_)); |
782 } else { | 779 } else { |
783 set_destination_next_ = true; | 780 set_destination_next_ = true; |
784 VLOG(1) << "Return address = " << recv_address_.ToString(); | 781 VLOG(1) << "Return address = " << recv_address_.ToString(); |
785 return_address_ = recv_address_; | 782 return_address_ = recv_address_; |
786 to_dest_pipe_->Send(packet_.Pass()); | 783 to_dest_pipe_->Send(std::move(packet_)); |
787 } | 784 } |
788 } | 785 } |
789 | 786 |
790 void ReadCallback(scoped_refptr<net::IOBuffer> recv_buf, int len) { | 787 void ReadCallback(scoped_refptr<net::IOBuffer> recv_buf, int len) { |
791 ProcessPacket(recv_buf, len); | 788 ProcessPacket(recv_buf, len); |
792 PollRead(); | 789 PollRead(); |
793 } | 790 } |
794 | 791 |
795 void PollRead() { | 792 void PollRead() { |
796 while (true) { | 793 while (true) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 net::IPEndPoint recv_address_; | 832 net::IPEndPoint recv_address_; |
836 scoped_ptr<Packet> packet_; | 833 scoped_ptr<Packet> packet_; |
837 | 834 |
838 // For sending. | 835 // For sending. |
839 bool blocked_; | 836 bool blocked_; |
840 | 837 |
841 base::WeakPtrFactory<UDPProxyImpl> weak_factory_; | 838 base::WeakPtrFactory<UDPProxyImpl> weak_factory_; |
842 }; | 839 }; |
843 | 840 |
844 void PacketSender::Send(scoped_ptr<Packet> packet) { | 841 void PacketSender::Send(scoped_ptr<Packet> packet) { |
845 udp_proxy_->Send(packet.Pass(), *destination_); | 842 udp_proxy_->Send(std::move(packet), *destination_); |
846 } | 843 } |
847 | 844 |
848 scoped_ptr<UDPProxy> UDPProxy::Create( | 845 scoped_ptr<UDPProxy> UDPProxy::Create( |
849 const net::IPEndPoint& local_port, | 846 const net::IPEndPoint& local_port, |
850 const net::IPEndPoint& destination, | 847 const net::IPEndPoint& destination, |
851 scoped_ptr<PacketPipe> to_dest_pipe, | 848 scoped_ptr<PacketPipe> to_dest_pipe, |
852 scoped_ptr<PacketPipe> from_dest_pipe, | 849 scoped_ptr<PacketPipe> from_dest_pipe, |
853 net::NetLog* net_log) { | 850 net::NetLog* net_log) { |
854 scoped_ptr<UDPProxy> ret(new UDPProxyImpl(local_port, | 851 scoped_ptr<UDPProxy> ret( |
855 destination, | 852 new UDPProxyImpl(local_port, destination, std::move(to_dest_pipe), |
856 to_dest_pipe.Pass(), | 853 std::move(from_dest_pipe), net_log)); |
857 from_dest_pipe.Pass(), | 854 return ret; |
858 net_log)); | |
859 return ret.Pass(); | |
860 } | 855 } |
861 | 856 |
862 } // namespace test | 857 } // namespace test |
863 } // namespace cast | 858 } // namespace cast |
864 } // namespace media | 859 } // namespace media |
OLD | NEW |