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" | 5 #include "media/cast/test/utility/udp_proxy.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 19 matching lines...) Expand all Loading... |
30 PacketPipe::~PacketPipe() {} | 30 PacketPipe::~PacketPipe() {} |
31 void PacketPipe::InitOnIOThread( | 31 void PacketPipe::InitOnIOThread( |
32 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 32 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
33 base::TickClock* clock) { | 33 base::TickClock* clock) { |
34 task_runner_ = task_runner; | 34 task_runner_ = task_runner; |
35 clock_ = clock; | 35 clock_ = clock; |
36 if (pipe_) { | 36 if (pipe_) { |
37 pipe_->InitOnIOThread(task_runner, clock); | 37 pipe_->InitOnIOThread(task_runner, clock); |
38 } | 38 } |
39 } | 39 } |
40 void PacketPipe::AppendToPipe(scoped_ptr<PacketPipe> pipe) { | 40 void PacketPipe::AppendToPipe(std::unique_ptr<PacketPipe> pipe) { |
41 if (pipe_) { | 41 if (pipe_) { |
42 pipe_->AppendToPipe(std::move(pipe)); | 42 pipe_->AppendToPipe(std::move(pipe)); |
43 } else { | 43 } else { |
44 pipe_ = std::move(pipe); | 44 pipe_ = std::move(pipe); |
45 } | 45 } |
46 } | 46 } |
47 | 47 |
48 // Roughly emulates a buffer inside a device. | 48 // Roughly emulates a buffer inside a device. |
49 // If the buffer is full, packets are dropped. | 49 // If the buffer is full, packets are dropped. |
50 // Packets are output at a maximum bandwidth. | 50 // Packets are output at a maximum bandwidth. |
51 class Buffer : public PacketPipe { | 51 class Buffer : public PacketPipe { |
52 public: | 52 public: |
53 Buffer(size_t buffer_size, double max_megabits_per_second) | 53 Buffer(size_t buffer_size, double max_megabits_per_second) |
54 : buffer_size_(0), | 54 : buffer_size_(0), |
55 max_buffer_size_(buffer_size), | 55 max_buffer_size_(buffer_size), |
56 max_megabits_per_second_(max_megabits_per_second), | 56 max_megabits_per_second_(max_megabits_per_second), |
57 weak_factory_(this) { | 57 weak_factory_(this) { |
58 CHECK_GT(max_buffer_size_, 0UL); | 58 CHECK_GT(max_buffer_size_, 0UL); |
59 CHECK_GT(max_megabits_per_second, 0); | 59 CHECK_GT(max_megabits_per_second, 0); |
60 } | 60 } |
61 | 61 |
62 void Send(scoped_ptr<Packet> packet) final { | 62 void Send(std::unique_ptr<Packet> packet) final { |
63 if (packet->size() + buffer_size_ <= max_buffer_size_) { | 63 if (packet->size() + buffer_size_ <= max_buffer_size_) { |
64 buffer_size_ += packet->size(); | 64 buffer_size_ += packet->size(); |
65 buffer_.push_back(linked_ptr<Packet>(packet.release())); | 65 buffer_.push_back(linked_ptr<Packet>(packet.release())); |
66 if (buffer_.size() == 1) { | 66 if (buffer_.size() == 1) { |
67 Schedule(); | 67 Schedule(); |
68 } | 68 } |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
72 private: | 72 private: |
(...skipping 11 matching lines...) Expand all Loading... |
84 void ProcessBuffer() { | 84 void ProcessBuffer() { |
85 int64_t bytes_to_send = static_cast<int64_t>( | 85 int64_t bytes_to_send = static_cast<int64_t>( |
86 (clock_->NowTicks() - last_schedule_).InSecondsF() * | 86 (clock_->NowTicks() - last_schedule_).InSecondsF() * |
87 max_megabits_per_second_ * 1E6 / 8); | 87 max_megabits_per_second_ * 1E6 / 8); |
88 if (bytes_to_send < static_cast<int64_t>(buffer_.front()->size())) { | 88 if (bytes_to_send < static_cast<int64_t>(buffer_.front()->size())) { |
89 bytes_to_send = buffer_.front()->size(); | 89 bytes_to_send = buffer_.front()->size(); |
90 } | 90 } |
91 while (!buffer_.empty() && | 91 while (!buffer_.empty() && |
92 static_cast<int64_t>(buffer_.front()->size()) <= bytes_to_send) { | 92 static_cast<int64_t>(buffer_.front()->size()) <= bytes_to_send) { |
93 CHECK(!buffer_.empty()); | 93 CHECK(!buffer_.empty()); |
94 scoped_ptr<Packet> packet(buffer_.front().release()); | 94 std::unique_ptr<Packet> packet(buffer_.front().release()); |
95 bytes_to_send -= packet->size(); | 95 bytes_to_send -= packet->size(); |
96 buffer_size_ -= packet->size(); | 96 buffer_size_ -= packet->size(); |
97 buffer_.pop_front(); | 97 buffer_.pop_front(); |
98 pipe_->Send(std::move(packet)); | 98 pipe_->Send(std::move(packet)); |
99 } | 99 } |
100 if (!buffer_.empty()) { | 100 if (!buffer_.empty()) { |
101 Schedule(); | 101 Schedule(); |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
105 std::deque<linked_ptr<Packet> > buffer_; | 105 std::deque<linked_ptr<Packet> > buffer_; |
106 base::TimeTicks last_schedule_; | 106 base::TimeTicks last_schedule_; |
107 size_t buffer_size_; | 107 size_t buffer_size_; |
108 size_t max_buffer_size_; | 108 size_t max_buffer_size_; |
109 double max_megabits_per_second_; // megabits per second | 109 double max_megabits_per_second_; // megabits per second |
110 base::WeakPtrFactory<Buffer> weak_factory_; | 110 base::WeakPtrFactory<Buffer> weak_factory_; |
111 }; | 111 }; |
112 | 112 |
113 scoped_ptr<PacketPipe> NewBuffer(size_t buffer_size, double bandwidth) { | 113 std::unique_ptr<PacketPipe> NewBuffer(size_t buffer_size, double bandwidth) { |
114 return scoped_ptr<PacketPipe>(new Buffer(buffer_size, bandwidth)); | 114 return std::unique_ptr<PacketPipe>(new Buffer(buffer_size, bandwidth)); |
115 } | 115 } |
116 | 116 |
117 class RandomDrop : public PacketPipe { | 117 class RandomDrop : public PacketPipe { |
118 public: | 118 public: |
119 RandomDrop(double drop_fraction) | 119 RandomDrop(double drop_fraction) |
120 : drop_fraction_(static_cast<int>(drop_fraction * RAND_MAX)) {} | 120 : drop_fraction_(static_cast<int>(drop_fraction * RAND_MAX)) {} |
121 | 121 |
122 void Send(scoped_ptr<Packet> packet) final { | 122 void Send(std::unique_ptr<Packet> packet) final { |
123 if (rand() > drop_fraction_) { | 123 if (rand() > drop_fraction_) { |
124 pipe_->Send(std::move(packet)); | 124 pipe_->Send(std::move(packet)); |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 private: | 128 private: |
129 int drop_fraction_; | 129 int drop_fraction_; |
130 }; | 130 }; |
131 | 131 |
132 scoped_ptr<PacketPipe> NewRandomDrop(double drop_fraction) { | 132 std::unique_ptr<PacketPipe> NewRandomDrop(double drop_fraction) { |
133 return scoped_ptr<PacketPipe>(new RandomDrop(drop_fraction)); | 133 return std::unique_ptr<PacketPipe>(new RandomDrop(drop_fraction)); |
134 } | 134 } |
135 | 135 |
136 class SimpleDelayBase : public PacketPipe { | 136 class SimpleDelayBase : public PacketPipe { |
137 public: | 137 public: |
138 SimpleDelayBase() : weak_factory_(this) {} | 138 SimpleDelayBase() : weak_factory_(this) {} |
139 ~SimpleDelayBase() override {} | 139 ~SimpleDelayBase() override {} |
140 | 140 |
141 void Send(scoped_ptr<Packet> packet) override { | 141 void Send(std::unique_ptr<Packet> packet) override { |
142 double seconds = GetDelay(); | 142 double seconds = GetDelay(); |
143 task_runner_->PostDelayedTask( | 143 task_runner_->PostDelayedTask( |
144 FROM_HERE, | 144 FROM_HERE, |
145 base::Bind(&SimpleDelayBase::SendInternal, weak_factory_.GetWeakPtr(), | 145 base::Bind(&SimpleDelayBase::SendInternal, weak_factory_.GetWeakPtr(), |
146 base::Passed(&packet)), | 146 base::Passed(&packet)), |
147 base::TimeDelta::FromMicroseconds(static_cast<int64_t>(seconds * 1E6))); | 147 base::TimeDelta::FromMicroseconds(static_cast<int64_t>(seconds * 1E6))); |
148 } | 148 } |
149 protected: | 149 protected: |
150 virtual double GetDelay() = 0; | 150 virtual double GetDelay() = 0; |
151 | 151 |
152 private: | 152 private: |
153 virtual void SendInternal(scoped_ptr<Packet> packet) { | 153 virtual void SendInternal(std::unique_ptr<Packet> packet) { |
154 pipe_->Send(std::move(packet)); | 154 pipe_->Send(std::move(packet)); |
155 } | 155 } |
156 | 156 |
157 base::WeakPtrFactory<SimpleDelayBase> weak_factory_; | 157 base::WeakPtrFactory<SimpleDelayBase> weak_factory_; |
158 }; | 158 }; |
159 | 159 |
160 class ConstantDelay : public SimpleDelayBase { | 160 class ConstantDelay : public SimpleDelayBase { |
161 public: | 161 public: |
162 ConstantDelay(double delay_seconds) : delay_seconds_(delay_seconds) {} | 162 ConstantDelay(double delay_seconds) : delay_seconds_(delay_seconds) {} |
163 double GetDelay() final { return delay_seconds_; } | 163 double GetDelay() final { return delay_seconds_; } |
164 | 164 |
165 private: | 165 private: |
166 double delay_seconds_; | 166 double delay_seconds_; |
167 }; | 167 }; |
168 | 168 |
169 scoped_ptr<PacketPipe> NewConstantDelay(double delay_seconds) { | 169 std::unique_ptr<PacketPipe> NewConstantDelay(double delay_seconds) { |
170 return scoped_ptr<PacketPipe>(new ConstantDelay(delay_seconds)); | 170 return std::unique_ptr<PacketPipe>(new ConstantDelay(delay_seconds)); |
171 } | 171 } |
172 | 172 |
173 class RandomUnsortedDelay : public SimpleDelayBase { | 173 class RandomUnsortedDelay : public SimpleDelayBase { |
174 public: | 174 public: |
175 RandomUnsortedDelay(double random_delay) : random_delay_(random_delay) {} | 175 RandomUnsortedDelay(double random_delay) : random_delay_(random_delay) {} |
176 | 176 |
177 double GetDelay() override { return random_delay_ * base::RandDouble(); } | 177 double GetDelay() override { return random_delay_ * base::RandDouble(); } |
178 | 178 |
179 private: | 179 private: |
180 double random_delay_; | 180 double random_delay_; |
181 }; | 181 }; |
182 | 182 |
183 scoped_ptr<PacketPipe> NewRandomUnsortedDelay(double random_delay) { | 183 std::unique_ptr<PacketPipe> NewRandomUnsortedDelay(double random_delay) { |
184 return scoped_ptr<PacketPipe>(new RandomUnsortedDelay(random_delay)); | 184 return std::unique_ptr<PacketPipe>(new RandomUnsortedDelay(random_delay)); |
185 } | 185 } |
186 | 186 |
187 class DuplicateAndDelay : public RandomUnsortedDelay { | 187 class DuplicateAndDelay : public RandomUnsortedDelay { |
188 public: | 188 public: |
189 DuplicateAndDelay(double delay_min, | 189 DuplicateAndDelay(double delay_min, |
190 double random_delay) : | 190 double random_delay) : |
191 RandomUnsortedDelay(random_delay), | 191 RandomUnsortedDelay(random_delay), |
192 delay_min_(delay_min) { | 192 delay_min_(delay_min) { |
193 } | 193 } |
194 void Send(scoped_ptr<Packet> packet) final { | 194 void Send(std::unique_ptr<Packet> packet) final { |
195 pipe_->Send(scoped_ptr<Packet>(new Packet(*packet.get()))); | 195 pipe_->Send(std::unique_ptr<Packet>(new Packet(*packet.get()))); |
196 RandomUnsortedDelay::Send(std::move(packet)); | 196 RandomUnsortedDelay::Send(std::move(packet)); |
197 } | 197 } |
198 double GetDelay() final { | 198 double GetDelay() final { |
199 return RandomUnsortedDelay::GetDelay() + delay_min_; | 199 return RandomUnsortedDelay::GetDelay() + delay_min_; |
200 } | 200 } |
201 private: | 201 private: |
202 double delay_min_; | 202 double delay_min_; |
203 }; | 203 }; |
204 | 204 |
205 scoped_ptr<PacketPipe> NewDuplicateAndDelay(double delay_min, | 205 std::unique_ptr<PacketPipe> NewDuplicateAndDelay(double delay_min, |
206 double random_delay) { | 206 double random_delay) { |
207 return scoped_ptr<PacketPipe>(new DuplicateAndDelay(delay_min, random_delay)); | 207 return std::unique_ptr<PacketPipe>( |
| 208 new DuplicateAndDelay(delay_min, random_delay)); |
208 } | 209 } |
209 | 210 |
210 class RandomSortedDelay : public PacketPipe { | 211 class RandomSortedDelay : public PacketPipe { |
211 public: | 212 public: |
212 RandomSortedDelay(double random_delay, | 213 RandomSortedDelay(double random_delay, |
213 double extra_delay, | 214 double extra_delay, |
214 double seconds_between_extra_delay) | 215 double seconds_between_extra_delay) |
215 : random_delay_(random_delay), | 216 : random_delay_(random_delay), |
216 extra_delay_(extra_delay), | 217 extra_delay_(extra_delay), |
217 seconds_between_extra_delay_(seconds_between_extra_delay), | 218 seconds_between_extra_delay_(seconds_between_extra_delay), |
218 weak_factory_(this) {} | 219 weak_factory_(this) {} |
219 | 220 |
220 void Send(scoped_ptr<Packet> packet) final { | 221 void Send(std::unique_ptr<Packet> packet) final { |
221 buffer_.push_back(linked_ptr<Packet>(packet.release())); | 222 buffer_.push_back(linked_ptr<Packet>(packet.release())); |
222 if (buffer_.size() == 1) { | 223 if (buffer_.size() == 1) { |
223 next_send_ = std::max( | 224 next_send_ = std::max( |
224 clock_->NowTicks() + | 225 clock_->NowTicks() + |
225 base::TimeDelta::FromSecondsD(base::RandDouble() * random_delay_), | 226 base::TimeDelta::FromSecondsD(base::RandDouble() * random_delay_), |
226 next_send_); | 227 next_send_); |
227 ProcessBuffer(); | 228 ProcessBuffer(); |
228 } | 229 } |
229 } | 230 } |
230 void InitOnIOThread( | 231 void InitOnIOThread( |
(...skipping 23 matching lines...) Expand all Loading... |
254 next_send_); | 255 next_send_); |
255 // An extra delay just happened, wait up to seconds_between_extra_delay_*2 | 256 // An extra delay just happened, wait up to seconds_between_extra_delay_*2 |
256 // before scheduling another one to make the average equal to | 257 // before scheduling another one to make the average equal to |
257 // seconds_between_extra_delay_. | 258 // seconds_between_extra_delay_. |
258 ScheduleExtraDelay(2.0); | 259 ScheduleExtraDelay(2.0); |
259 } | 260 } |
260 | 261 |
261 void ProcessBuffer() { | 262 void ProcessBuffer() { |
262 base::TimeTicks now = clock_->NowTicks(); | 263 base::TimeTicks now = clock_->NowTicks(); |
263 while (!buffer_.empty() && next_send_ <= now) { | 264 while (!buffer_.empty() && next_send_ <= now) { |
264 scoped_ptr<Packet> packet(buffer_.front().release()); | 265 std::unique_ptr<Packet> packet(buffer_.front().release()); |
265 pipe_->Send(std::move(packet)); | 266 pipe_->Send(std::move(packet)); |
266 buffer_.pop_front(); | 267 buffer_.pop_front(); |
267 | 268 |
268 next_send_ += base::TimeDelta::FromSecondsD( | 269 next_send_ += base::TimeDelta::FromSecondsD( |
269 base::RandDouble() * random_delay_); | 270 base::RandDouble() * random_delay_); |
270 } | 271 } |
271 | 272 |
272 if (!buffer_.empty()) { | 273 if (!buffer_.empty()) { |
273 task_runner_->PostDelayedTask( | 274 task_runner_->PostDelayedTask( |
274 FROM_HERE, | 275 FROM_HERE, |
275 base::Bind(&RandomSortedDelay::ProcessBuffer, | 276 base::Bind(&RandomSortedDelay::ProcessBuffer, |
276 weak_factory_.GetWeakPtr()), | 277 weak_factory_.GetWeakPtr()), |
277 next_send_ - now); | 278 next_send_ - now); |
278 } | 279 } |
279 } | 280 } |
280 | 281 |
281 base::TimeTicks block_until_; | 282 base::TimeTicks block_until_; |
282 std::deque<linked_ptr<Packet> > buffer_; | 283 std::deque<linked_ptr<Packet> > buffer_; |
283 double random_delay_; | 284 double random_delay_; |
284 double extra_delay_; | 285 double extra_delay_; |
285 double seconds_between_extra_delay_; | 286 double seconds_between_extra_delay_; |
286 base::TimeTicks next_send_; | 287 base::TimeTicks next_send_; |
287 base::WeakPtrFactory<RandomSortedDelay> weak_factory_; | 288 base::WeakPtrFactory<RandomSortedDelay> weak_factory_; |
288 }; | 289 }; |
289 | 290 |
290 scoped_ptr<PacketPipe> NewRandomSortedDelay( | 291 std::unique_ptr<PacketPipe> NewRandomSortedDelay( |
291 double random_delay, | 292 double random_delay, |
292 double extra_delay, | 293 double extra_delay, |
293 double seconds_between_extra_delay) { | 294 double seconds_between_extra_delay) { |
294 return scoped_ptr<PacketPipe>(new RandomSortedDelay( | 295 return std::unique_ptr<PacketPipe>(new RandomSortedDelay( |
295 random_delay, extra_delay, seconds_between_extra_delay)); | 296 random_delay, extra_delay, seconds_between_extra_delay)); |
296 } | 297 } |
297 | 298 |
298 class NetworkGlitchPipe : public PacketPipe { | 299 class NetworkGlitchPipe : public PacketPipe { |
299 public: | 300 public: |
300 NetworkGlitchPipe(double average_work_time, double average_outage_time) | 301 NetworkGlitchPipe(double average_work_time, double average_outage_time) |
301 : works_(false), | 302 : works_(false), |
302 max_work_time_(average_work_time * 2), | 303 max_work_time_(average_work_time * 2), |
303 max_outage_time_(average_outage_time * 2), | 304 max_outage_time_(average_outage_time * 2), |
304 weak_factory_(this) {} | 305 weak_factory_(this) {} |
305 | 306 |
306 void InitOnIOThread( | 307 void InitOnIOThread( |
307 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 308 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
308 base::TickClock* clock) final { | 309 base::TickClock* clock) final { |
309 PacketPipe::InitOnIOThread(task_runner, clock); | 310 PacketPipe::InitOnIOThread(task_runner, clock); |
310 Flip(); | 311 Flip(); |
311 } | 312 } |
312 | 313 |
313 void Send(scoped_ptr<Packet> packet) final { | 314 void Send(std::unique_ptr<Packet> packet) final { |
314 if (works_) { | 315 if (works_) { |
315 pipe_->Send(std::move(packet)); | 316 pipe_->Send(std::move(packet)); |
316 } | 317 } |
317 } | 318 } |
318 | 319 |
319 private: | 320 private: |
320 void Flip() { | 321 void Flip() { |
321 works_ = !works_; | 322 works_ = !works_; |
322 double seconds = base::RandDouble() * | 323 double seconds = base::RandDouble() * |
323 (works_ ? max_work_time_ : max_outage_time_); | 324 (works_ ? max_work_time_ : max_outage_time_); |
324 int64_t microseconds = static_cast<int64_t>(seconds * 1E6); | 325 int64_t microseconds = static_cast<int64_t>(seconds * 1E6); |
325 task_runner_->PostDelayedTask( | 326 task_runner_->PostDelayedTask( |
326 FROM_HERE, | 327 FROM_HERE, |
327 base::Bind(&NetworkGlitchPipe::Flip, weak_factory_.GetWeakPtr()), | 328 base::Bind(&NetworkGlitchPipe::Flip, weak_factory_.GetWeakPtr()), |
328 base::TimeDelta::FromMicroseconds(microseconds)); | 329 base::TimeDelta::FromMicroseconds(microseconds)); |
329 } | 330 } |
330 | 331 |
331 bool works_; | 332 bool works_; |
332 double max_work_time_; | 333 double max_work_time_; |
333 double max_outage_time_; | 334 double max_outage_time_; |
334 base::WeakPtrFactory<NetworkGlitchPipe> weak_factory_; | 335 base::WeakPtrFactory<NetworkGlitchPipe> weak_factory_; |
335 }; | 336 }; |
336 | 337 |
337 scoped_ptr<PacketPipe> NewNetworkGlitchPipe(double average_work_time, | 338 std::unique_ptr<PacketPipe> NewNetworkGlitchPipe(double average_work_time, |
338 double average_outage_time) { | 339 double average_outage_time) { |
339 return scoped_ptr<PacketPipe>( | 340 return std::unique_ptr<PacketPipe>( |
340 new NetworkGlitchPipe(average_work_time, average_outage_time)); | 341 new NetworkGlitchPipe(average_work_time, average_outage_time)); |
341 } | 342 } |
342 | 343 |
343 | 344 |
344 // Internal buffer object for a client of the IPP model. | 345 // Internal buffer object for a client of the IPP model. |
345 class InterruptedPoissonProcess::InternalBuffer : public PacketPipe { | 346 class InterruptedPoissonProcess::InternalBuffer : public PacketPipe { |
346 public: | 347 public: |
347 InternalBuffer(base::WeakPtr<InterruptedPoissonProcess> ipp, | 348 InternalBuffer(base::WeakPtr<InterruptedPoissonProcess> ipp, |
348 size_t size) | 349 size_t size) |
349 : ipp_(ipp), | 350 : ipp_(ipp), |
350 stored_size_(0), | 351 stored_size_(0), |
351 stored_limit_(size), | 352 stored_limit_(size), |
352 clock_(NULL), | 353 clock_(NULL), |
353 weak_factory_(this) { | 354 weak_factory_(this) { |
354 } | 355 } |
355 | 356 |
356 void Send(scoped_ptr<Packet> packet) final { | 357 void Send(std::unique_ptr<Packet> packet) final { |
357 // Drop if buffer is full. | 358 // Drop if buffer is full. |
358 if (stored_size_ >= stored_limit_) | 359 if (stored_size_ >= stored_limit_) |
359 return; | 360 return; |
360 stored_size_ += packet->size(); | 361 stored_size_ += packet->size(); |
361 buffer_.push_back(linked_ptr<Packet>(packet.release())); | 362 buffer_.push_back(linked_ptr<Packet>(packet.release())); |
362 buffer_time_.push_back(clock_->NowTicks()); | 363 buffer_time_.push_back(clock_->NowTicks()); |
363 DCHECK(buffer_.size() == buffer_time_.size()); | 364 DCHECK(buffer_.size() == buffer_time_.size()); |
364 } | 365 } |
365 | 366 |
366 void InitOnIOThread( | 367 void InitOnIOThread( |
367 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 368 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
368 base::TickClock* clock) final { | 369 base::TickClock* clock) final { |
369 clock_ = clock; | 370 clock_ = clock; |
370 if (ipp_) | 371 if (ipp_) |
371 ipp_->InitOnIOThread(task_runner, clock); | 372 ipp_->InitOnIOThread(task_runner, clock); |
372 PacketPipe::InitOnIOThread(task_runner, clock); | 373 PacketPipe::InitOnIOThread(task_runner, clock); |
373 } | 374 } |
374 | 375 |
375 void SendOnePacket() { | 376 void SendOnePacket() { |
376 scoped_ptr<Packet> packet(buffer_.front().release()); | 377 std::unique_ptr<Packet> packet(buffer_.front().release()); |
377 stored_size_ -= packet->size(); | 378 stored_size_ -= packet->size(); |
378 buffer_.pop_front(); | 379 buffer_.pop_front(); |
379 buffer_time_.pop_front(); | 380 buffer_time_.pop_front(); |
380 pipe_->Send(std::move(packet)); | 381 pipe_->Send(std::move(packet)); |
381 DCHECK(buffer_.size() == buffer_time_.size()); | 382 DCHECK(buffer_.size() == buffer_time_.size()); |
382 } | 383 } |
383 | 384 |
384 bool Empty() const { | 385 bool Empty() const { |
385 return buffer_.empty(); | 386 return buffer_.empty(); |
386 } | 387 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 // Already initialized and started. | 434 // Already initialized and started. |
434 if (task_runner_.get() && clock_) | 435 if (task_runner_.get() && clock_) |
435 return; | 436 return; |
436 task_runner_ = task_runner; | 437 task_runner_ = task_runner; |
437 clock_ = clock; | 438 clock_ = clock; |
438 UpdateRates(); | 439 UpdateRates(); |
439 SwitchOn(); | 440 SwitchOn(); |
440 SendPacket(); | 441 SendPacket(); |
441 } | 442 } |
442 | 443 |
443 scoped_ptr<PacketPipe> InterruptedPoissonProcess::NewBuffer(size_t size) { | 444 std::unique_ptr<PacketPipe> InterruptedPoissonProcess::NewBuffer(size_t size) { |
444 scoped_ptr<InternalBuffer> buffer( | 445 std::unique_ptr<InternalBuffer> buffer( |
445 new InternalBuffer(weak_factory_.GetWeakPtr(), size)); | 446 new InternalBuffer(weak_factory_.GetWeakPtr(), size)); |
446 send_buffers_.push_back(buffer->GetWeakPtr()); | 447 send_buffers_.push_back(buffer->GetWeakPtr()); |
447 return std::move(buffer); | 448 return std::move(buffer); |
448 } | 449 } |
449 | 450 |
450 base::TimeDelta InterruptedPoissonProcess::NextEvent(double rate) { | 451 base::TimeDelta InterruptedPoissonProcess::NextEvent(double rate) { |
451 // Rate is per milliseconds. | 452 // Rate is per milliseconds. |
452 // The time until next event is exponentially distributed to the | 453 // The time until next event is exponentially distributed to the |
453 // inverse of |rate|. | 454 // inverse of |rate|. |
454 return base::TimeDelta::FromMillisecondsD( | 455 return base::TimeDelta::FromMillisecondsD( |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 break; | 539 break; |
539 } | 540 } |
540 } | 541 } |
541 | 542 |
542 class UDPProxyImpl; | 543 class UDPProxyImpl; |
543 | 544 |
544 class PacketSender : public PacketPipe { | 545 class PacketSender : public PacketPipe { |
545 public: | 546 public: |
546 PacketSender(UDPProxyImpl* udp_proxy, const net::IPEndPoint* destination) | 547 PacketSender(UDPProxyImpl* udp_proxy, const net::IPEndPoint* destination) |
547 : udp_proxy_(udp_proxy), destination_(destination) {} | 548 : udp_proxy_(udp_proxy), destination_(destination) {} |
548 void Send(scoped_ptr<Packet> packet) final; | 549 void Send(std::unique_ptr<Packet> packet) final; |
549 void AppendToPipe(scoped_ptr<PacketPipe> pipe) final { NOTREACHED(); } | 550 void AppendToPipe(std::unique_ptr<PacketPipe> pipe) final { NOTREACHED(); } |
550 | 551 |
551 private: | 552 private: |
552 UDPProxyImpl* udp_proxy_; | 553 UDPProxyImpl* udp_proxy_; |
553 const net::IPEndPoint* destination_; // not owned | 554 const net::IPEndPoint* destination_; // not owned |
554 }; | 555 }; |
555 | 556 |
556 namespace { | 557 namespace { |
557 void BuildPipe(scoped_ptr<PacketPipe>* pipe, PacketPipe* next) { | 558 void BuildPipe(std::unique_ptr<PacketPipe>* pipe, PacketPipe* next) { |
558 if (*pipe) { | 559 if (*pipe) { |
559 (*pipe)->AppendToPipe(scoped_ptr<PacketPipe>(next)); | 560 (*pipe)->AppendToPipe(std::unique_ptr<PacketPipe>(next)); |
560 } else { | 561 } else { |
561 pipe->reset(next); | 562 pipe->reset(next); |
562 } | 563 } |
563 } | 564 } |
564 } // namespace | 565 } // namespace |
565 | 566 |
566 scoped_ptr<PacketPipe> GoodNetwork() { | 567 std::unique_ptr<PacketPipe> GoodNetwork() { |
567 // This represents the buffer on the sender. | 568 // This represents the buffer on the sender. |
568 scoped_ptr<PacketPipe> pipe; | 569 std::unique_ptr<PacketPipe> pipe; |
569 BuildPipe(&pipe, new Buffer(2 << 20, 50)); | 570 BuildPipe(&pipe, new Buffer(2 << 20, 50)); |
570 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 571 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
571 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 2E-3, 3)); | 572 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 2E-3, 3)); |
572 // This represents the buffer on the receiving device. | 573 // This represents the buffer on the receiving device. |
573 BuildPipe(&pipe, new Buffer(2 << 20, 50)); | 574 BuildPipe(&pipe, new Buffer(2 << 20, 50)); |
574 return pipe; | 575 return pipe; |
575 } | 576 } |
576 | 577 |
577 scoped_ptr<PacketPipe> WifiNetwork() { | 578 std::unique_ptr<PacketPipe> WifiNetwork() { |
578 // This represents the buffer on the sender. | 579 // This represents the buffer on the sender. |
579 scoped_ptr<PacketPipe> pipe; | 580 std::unique_ptr<PacketPipe> pipe; |
580 BuildPipe(&pipe, new Buffer(256 << 10, 20)); | 581 BuildPipe(&pipe, new Buffer(256 << 10, 20)); |
581 BuildPipe(&pipe, new RandomDrop(0.005)); | 582 BuildPipe(&pipe, new RandomDrop(0.005)); |
582 // This represents the buffer on the router. | 583 // This represents the buffer on the router. |
583 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 584 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
584 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); | 585 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); |
585 BuildPipe(&pipe, new Buffer(256 << 10, 20)); | 586 BuildPipe(&pipe, new Buffer(256 << 10, 20)); |
586 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 587 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
587 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); | 588 BuildPipe(&pipe, new RandomSortedDelay(1E-3, 20E-3, 3)); |
588 BuildPipe(&pipe, new RandomDrop(0.005)); | 589 BuildPipe(&pipe, new RandomDrop(0.005)); |
589 // This represents the buffer on the receiving device. | 590 // This represents the buffer on the receiving device. |
590 BuildPipe(&pipe, new Buffer(256 << 10, 20)); | 591 BuildPipe(&pipe, new Buffer(256 << 10, 20)); |
591 return pipe; | 592 return pipe; |
592 } | 593 } |
593 | 594 |
594 scoped_ptr<PacketPipe> BadNetwork() { | 595 std::unique_ptr<PacketPipe> BadNetwork() { |
595 scoped_ptr<PacketPipe> pipe; | 596 std::unique_ptr<PacketPipe> pipe; |
596 // This represents the buffer on the sender. | 597 // This represents the buffer on the sender. |
597 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s | 598 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s |
598 BuildPipe(&pipe, new RandomDrop(0.05)); // 5% packet drop | 599 BuildPipe(&pipe, new RandomDrop(0.05)); // 5% packet drop |
599 BuildPipe(&pipe, new RandomSortedDelay(2E-3, 20E-3, 1)); | 600 BuildPipe(&pipe, new RandomSortedDelay(2E-3, 20E-3, 1)); |
600 // This represents the buffer on the router. | 601 // This represents the buffer on the router. |
601 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 4mbit/s | 602 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 4mbit/s |
602 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 603 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
603 // Random 40ms every other second | 604 // Random 40ms every other second |
604 // BuildPipe(&pipe, new NetworkGlitchPipe(2, 40E-1)); | 605 // BuildPipe(&pipe, new NetworkGlitchPipe(2, 40E-1)); |
605 BuildPipe(&pipe, new RandomUnsortedDelay(5E-3)); | 606 BuildPipe(&pipe, new RandomUnsortedDelay(5E-3)); |
606 // This represents the buffer on the receiving device. | 607 // This represents the buffer on the receiving device. |
607 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s | 608 BuildPipe(&pipe, new Buffer(64 << 10, 5)); // 64 kb buf, 5mbit/s |
608 return pipe; | 609 return pipe; |
609 } | 610 } |
610 | 611 |
611 | 612 std::unique_ptr<PacketPipe> EvilNetwork() { |
612 scoped_ptr<PacketPipe> EvilNetwork() { | |
613 // This represents the buffer on the sender. | 613 // This represents the buffer on the sender. |
614 scoped_ptr<PacketPipe> pipe; | 614 std::unique_ptr<PacketPipe> pipe; |
615 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 |
616 // This represents the buffer on the router. | 616 // This represents the buffer on the router. |
617 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop | 617 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop |
618 BuildPipe(&pipe, new RandomSortedDelay(20E-3, 60E-3, 1)); | 618 BuildPipe(&pipe, new RandomSortedDelay(20E-3, 60E-3, 1)); |
619 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 |
620 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop | 620 BuildPipe(&pipe, new RandomDrop(0.1)); // 10% packet drop |
621 BuildPipe(&pipe, new ConstantDelay(1E-3)); | 621 BuildPipe(&pipe, new ConstantDelay(1E-3)); |
622 BuildPipe(&pipe, new NetworkGlitchPipe(2.0, 0.3)); | 622 BuildPipe(&pipe, new NetworkGlitchPipe(2.0, 0.3)); |
623 BuildPipe(&pipe, new RandomUnsortedDelay(20E-3)); | 623 BuildPipe(&pipe, new RandomUnsortedDelay(20E-3)); |
624 // This represents the buffer on the receiving device. | 624 // This represents the buffer on the receiving device. |
625 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 |
626 return pipe; | 626 return pipe; |
627 } | 627 } |
628 | 628 |
629 scoped_ptr<InterruptedPoissonProcess> DefaultInterruptedPoissonProcess() { | 629 std::unique_ptr<InterruptedPoissonProcess> DefaultInterruptedPoissonProcess() { |
630 // 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. |
631 // They are experimentally tested to demonstrate challenging network | 631 // They are experimentally tested to demonstrate challenging network |
632 // conditions. The average bitrate is about 2mbits/s. | 632 // conditions. The average bitrate is about 2mbits/s. |
633 | 633 |
634 // 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 |
635 // per millisecond. The average changes and rotates every second. | 635 // per millisecond. The average changes and rotates every second. |
636 std::vector<double> average_rates; | 636 std::vector<double> average_rates; |
637 average_rates.push_back(0.609); | 637 average_rates.push_back(0.609); |
638 average_rates.push_back(0.495); | 638 average_rates.push_back(0.495); |
639 average_rates.push_back(0.561); | 639 average_rates.push_back(0.561); |
640 average_rates.push_back(0.458); | 640 average_rates.push_back(0.458); |
641 average_rates.push_back(0.538); | 641 average_rates.push_back(0.538); |
642 average_rates.push_back(0.513); | 642 average_rates.push_back(0.513); |
643 average_rates.push_back(0.585); | 643 average_rates.push_back(0.585); |
644 average_rates.push_back(0.592); | 644 average_rates.push_back(0.592); |
645 average_rates.push_back(0.658); | 645 average_rates.push_back(0.658); |
646 average_rates.push_back(0.556); | 646 average_rates.push_back(0.556); |
647 average_rates.push_back(0.371); | 647 average_rates.push_back(0.371); |
648 average_rates.push_back(0.595); | 648 average_rates.push_back(0.595); |
649 average_rates.push_back(0.490); | 649 average_rates.push_back(0.490); |
650 average_rates.push_back(0.980); | 650 average_rates.push_back(0.980); |
651 average_rates.push_back(0.781); | 651 average_rates.push_back(0.781); |
652 average_rates.push_back(0.463); | 652 average_rates.push_back(0.463); |
653 | 653 |
654 const double burstiness = 0.609; | 654 const double burstiness = 0.609; |
655 const double variance = 4.1; | 655 const double variance = 4.1; |
656 | 656 |
657 scoped_ptr<InterruptedPoissonProcess> ipp( | 657 std::unique_ptr<InterruptedPoissonProcess> ipp( |
658 new InterruptedPoissonProcess( | 658 new InterruptedPoissonProcess(average_rates, burstiness, variance, 0)); |
659 average_rates, burstiness, variance, 0)); | |
660 return ipp; | 659 return ipp; |
661 } | 660 } |
662 | 661 |
663 class UDPProxyImpl : public UDPProxy { | 662 class UDPProxyImpl : public UDPProxy { |
664 public: | 663 public: |
665 UDPProxyImpl(const net::IPEndPoint& local_port, | 664 UDPProxyImpl(const net::IPEndPoint& local_port, |
666 const net::IPEndPoint& destination, | 665 const net::IPEndPoint& destination, |
667 scoped_ptr<PacketPipe> to_dest_pipe, | 666 std::unique_ptr<PacketPipe> to_dest_pipe, |
668 scoped_ptr<PacketPipe> from_dest_pipe, | 667 std::unique_ptr<PacketPipe> from_dest_pipe, |
669 net::NetLog* net_log) | 668 net::NetLog* net_log) |
670 : local_port_(local_port), | 669 : local_port_(local_port), |
671 destination_(destination), | 670 destination_(destination), |
672 destination_is_mutable_(destination.address().empty()), | 671 destination_is_mutable_(destination.address().empty()), |
673 proxy_thread_("media::cast::test::UdpProxy Thread"), | 672 proxy_thread_("media::cast::test::UdpProxy Thread"), |
674 to_dest_pipe_(std::move(to_dest_pipe)), | 673 to_dest_pipe_(std::move(to_dest_pipe)), |
675 from_dest_pipe_(std::move(from_dest_pipe)), | 674 from_dest_pipe_(std::move(from_dest_pipe)), |
676 blocked_(false), | 675 blocked_(false), |
677 weak_factory_(this) { | 676 weak_factory_(this) { |
678 proxy_thread_.StartWithOptions( | 677 proxy_thread_.StartWithOptions( |
(...skipping 12 matching lines...) Expand all Loading... |
691 base::WaitableEvent stop_event(false, false); | 690 base::WaitableEvent stop_event(false, false); |
692 proxy_thread_.task_runner()->PostTask( | 691 proxy_thread_.task_runner()->PostTask( |
693 FROM_HERE, | 692 FROM_HERE, |
694 base::Bind(&UDPProxyImpl::Stop, | 693 base::Bind(&UDPProxyImpl::Stop, |
695 base::Unretained(this), | 694 base::Unretained(this), |
696 base::Unretained(&stop_event))); | 695 base::Unretained(&stop_event))); |
697 stop_event.Wait(); | 696 stop_event.Wait(); |
698 proxy_thread_.Stop(); | 697 proxy_thread_.Stop(); |
699 } | 698 } |
700 | 699 |
701 void Send(scoped_ptr<Packet> packet, | 700 void Send(std::unique_ptr<Packet> packet, |
702 const net::IPEndPoint& destination) { | 701 const net::IPEndPoint& destination) { |
703 if (blocked_) { | 702 if (blocked_) { |
704 LOG(ERROR) << "Cannot write packet right now: blocked"; | 703 LOG(ERROR) << "Cannot write packet right now: blocked"; |
705 return; | 704 return; |
706 } | 705 } |
707 | 706 |
708 VLOG(1) << "Sending packet, len = " << packet->size(); | 707 VLOG(1) << "Sending packet, len = " << packet->size(); |
709 // We ignore all problems, callbacks and errors. | 708 // We ignore all problems, callbacks and errors. |
710 // If it didn't work we just drop the packet at and call it a day. | 709 // If it didn't work we just drop the packet at and call it a day. |
711 scoped_refptr<net::IOBuffer> buf = | 710 scoped_refptr<net::IOBuffer> buf = |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 &recv_address_, | 799 &recv_address_, |
801 base::Bind( | 800 base::Bind( |
802 &UDPProxyImpl::ReadCallback, base::Unretained(this), recv_buf)); | 801 &UDPProxyImpl::ReadCallback, base::Unretained(this), recv_buf)); |
803 if (len == net::ERR_IO_PENDING) | 802 if (len == net::ERR_IO_PENDING) |
804 break; | 803 break; |
805 ProcessPacket(recv_buf, len); | 804 ProcessPacket(recv_buf, len); |
806 } | 805 } |
807 } | 806 } |
808 | 807 |
809 void AllowWrite(scoped_refptr<net::IOBuffer> buf, | 808 void AllowWrite(scoped_refptr<net::IOBuffer> buf, |
810 scoped_ptr<Packet> packet, | 809 std::unique_ptr<Packet> packet, |
811 int unused_len) { | 810 int unused_len) { |
812 DCHECK(blocked_); | 811 DCHECK(blocked_); |
813 blocked_ = false; | 812 blocked_ = false; |
814 } | 813 } |
815 | 814 |
816 // Input | 815 // Input |
817 net::IPEndPoint local_port_; | 816 net::IPEndPoint local_port_; |
818 | 817 |
819 net::IPEndPoint destination_; | 818 net::IPEndPoint destination_; |
820 bool destination_is_mutable_; | 819 bool destination_is_mutable_; |
821 | 820 |
822 net::IPEndPoint return_address_; | 821 net::IPEndPoint return_address_; |
823 bool set_destination_next_; | 822 bool set_destination_next_; |
824 | 823 |
825 base::DefaultTickClock tick_clock_; | 824 base::DefaultTickClock tick_clock_; |
826 base::Thread proxy_thread_; | 825 base::Thread proxy_thread_; |
827 scoped_ptr<net::UDPServerSocket> socket_; | 826 std::unique_ptr<net::UDPServerSocket> socket_; |
828 scoped_ptr<PacketPipe> to_dest_pipe_; | 827 std::unique_ptr<PacketPipe> to_dest_pipe_; |
829 scoped_ptr<PacketPipe> from_dest_pipe_; | 828 std::unique_ptr<PacketPipe> from_dest_pipe_; |
830 | 829 |
831 // For receiving. | 830 // For receiving. |
832 net::IPEndPoint recv_address_; | 831 net::IPEndPoint recv_address_; |
833 scoped_ptr<Packet> packet_; | 832 std::unique_ptr<Packet> packet_; |
834 | 833 |
835 // For sending. | 834 // For sending. |
836 bool blocked_; | 835 bool blocked_; |
837 | 836 |
838 base::WeakPtrFactory<UDPProxyImpl> weak_factory_; | 837 base::WeakPtrFactory<UDPProxyImpl> weak_factory_; |
839 }; | 838 }; |
840 | 839 |
841 void PacketSender::Send(scoped_ptr<Packet> packet) { | 840 void PacketSender::Send(std::unique_ptr<Packet> packet) { |
842 udp_proxy_->Send(std::move(packet), *destination_); | 841 udp_proxy_->Send(std::move(packet), *destination_); |
843 } | 842 } |
844 | 843 |
845 scoped_ptr<UDPProxy> UDPProxy::Create( | 844 std::unique_ptr<UDPProxy> UDPProxy::Create( |
846 const net::IPEndPoint& local_port, | 845 const net::IPEndPoint& local_port, |
847 const net::IPEndPoint& destination, | 846 const net::IPEndPoint& destination, |
848 scoped_ptr<PacketPipe> to_dest_pipe, | 847 std::unique_ptr<PacketPipe> to_dest_pipe, |
849 scoped_ptr<PacketPipe> from_dest_pipe, | 848 std::unique_ptr<PacketPipe> from_dest_pipe, |
850 net::NetLog* net_log) { | 849 net::NetLog* net_log) { |
851 scoped_ptr<UDPProxy> ret( | 850 std::unique_ptr<UDPProxy> ret( |
852 new UDPProxyImpl(local_port, destination, std::move(to_dest_pipe), | 851 new UDPProxyImpl(local_port, destination, std::move(to_dest_pipe), |
853 std::move(from_dest_pipe), net_log)); | 852 std::move(from_dest_pipe), net_log)); |
854 return ret; | 853 return ret; |
855 } | 854 } |
856 | 855 |
857 } // namespace test | 856 } // namespace test |
858 } // namespace cast | 857 } // namespace cast |
859 } // namespace media | 858 } // namespace media |
OLD | NEW |