| 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 |