diff options
author | hubbe@chromium.org <hubbe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 01:33:53 +0000 |
---|---|---|
committer | hubbe@chromium.org <hubbe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 01:33:53 +0000 |
commit | 4c10bf30f3281897804c9158063495b212f537da (patch) | |
tree | 0eb8fefc358d6cdf20f744550d091ea7488b1938 /media | |
parent | bd519e3d886c0ee43f98af66c061216c5c6b404b (diff) | |
download | chromium_src-4c10bf30f3281897804c9158063495b212f537da.zip chromium_src-4c10bf30f3281897804c9158063495b212f537da.tar.gz chromium_src-4c10bf30f3281897804c9158063495b212f537da.tar.bz2 |
Add another network profile to the udp proxy.
This adds a network profile called "bad" which is somewhere in between "wifi" and "evil".
Also add bandwidth monitoring to the standalone program.
Review URL: https://codereview.chromium.org/261013014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269136 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/cast/test/utility/udp_proxy.cc | 20 | ||||
-rw-r--r-- | media/cast/test/utility/udp_proxy.h | 6 | ||||
-rw-r--r-- | media/cast/test/utility/udp_proxy_main.cc | 116 |
3 files changed, 139 insertions, 3 deletions
diff --git a/media/cast/test/utility/udp_proxy.cc b/media/cast/test/utility/udp_proxy.cc index eed3744..1132815 100644 --- a/media/cast/test/utility/udp_proxy.cc +++ b/media/cast/test/utility/udp_proxy.cc @@ -385,6 +385,24 @@ scoped_ptr<PacketPipe> WifiNetwork() { return pipe.Pass(); } +scoped_ptr<PacketPipe> BadNetwork() { + scoped_ptr<PacketPipe> pipe; + // This represents the buffer on the sender. + BuildPipe(&pipe, new Buffer(64 << 10, 5000000)); // 64 kb buf, 5mbit/s + BuildPipe(&pipe, new RandomDrop(0.05)); // 5% packet drop + BuildPipe(&pipe, new RandomSortedDelay(2E-3, 20E-3, 1)); + // This represents the buffer on the router. + BuildPipe(&pipe, new Buffer(64 << 10, 2000000)); // 64 kb buf, 2mbit/s + BuildPipe(&pipe, new ConstantDelay(1E-3)); + // Random 40ms every other second + // BuildPipe(&pipe, new NetworkGlitchPipe(2, 40E-1)); + BuildPipe(&pipe, new RandomUnsortedDelay(5E-3)); + // This represents the buffer on the receiving device. + BuildPipe(&pipe, new Buffer(64 << 10, 4000000)); // 64 kb buf, 4mbit/s + return pipe.Pass(); +} + + scoped_ptr<PacketPipe> EvilNetwork() { // This represents the buffer on the sender. scoped_ptr<PacketPipe> pipe; @@ -413,7 +431,7 @@ class UDPProxyImpl : public UDPProxy { destination_(destination), proxy_thread_("media::cast::test::UdpProxy Thread"), to_dest_pipe_(to_dest_pipe.Pass()), - from_dest_pipe_(to_dest_pipe.Pass()) { + from_dest_pipe_(from_dest_pipe.Pass()) { proxy_thread_.StartWithOptions( base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); base::WaitableEvent start_event(false, false); diff --git a/media/cast/test/utility/udp_proxy.h b/media/cast/test/utility/udp_proxy.h index 41c686e..9dce0cf 100644 --- a/media/cast/test/utility/udp_proxy.h +++ b/media/cast/test/utility/udp_proxy.h @@ -93,8 +93,14 @@ scoped_ptr<PacketPipe> NewNetworkGlitchPipe(double average_work_time, // good wifi network. ~5mbit, 1% packet loss, ~3ms latency. scoped_ptr<PacketPipe> WifiNetwork(); +// This method builds a stack of PacketPipes to emulate a +// bad wifi network. ~2mbit, 5% packet loss, ~7ms latency +// 40ms dropouts every ~2 seconds. Can reorder packets. +scoped_ptr<PacketPipe> BadNetwork(); + // This method builds a stack of PacketPipes to emulate a crappy wifi network. // ~1mbit, 20% packet loss, ~40ms latency and packets can get reordered. +// 300ms drouputs every ~2 seconds. scoped_ptr<PacketPipe> EvilNetwork(); } // namespace test diff --git a/media/cast/test/utility/udp_proxy_main.cc b/media/cast/test/utility/udp_proxy_main.cc index 68a885f..0202d8c 100644 --- a/media/cast/test/utility/udp_proxy_main.cc +++ b/media/cast/test/utility/udp_proxy_main.cc @@ -4,6 +4,7 @@ #include <cstdio> #include <cstdlib> +#include <deque> #include <string> #include "base/at_exit.h" @@ -13,11 +14,112 @@ #include "base/message_loop/message_loop.h" #include "media/cast/test/utility/udp_proxy.h" +base::TimeTicks last_printout; + +class ByteCounter { + public: + ByteCounter() : bytes_(0), packets_(0) { + push(base::TimeTicks::Now()); + } + + base::TimeDelta time_range() { + return time_data_.back() - time_data_.front(); + } + + void push(base::TimeTicks now) { + byte_data_.push_back(bytes_); + packet_data_.push_back(packets_); + time_data_.push_back(now); + while (time_range().InSeconds() > 10) { + byte_data_.pop_front(); + packet_data_.pop_front(); + time_data_.pop_front(); + } + } + + double megabits_per_second() { + double megabits = (byte_data_.back() - byte_data_.front()) * 8 / 1E6; + return megabits / time_range().InSecondsF(); + } + + double packets_per_second() { + double packets = packet_data_.back()- packet_data_.front(); + return packets / time_range().InSecondsF(); + } + + void Increment(uint64 x) { + bytes_ += x; + packets_ ++; + } + + private: + uint64 bytes_; + uint64 packets_; + std::deque<uint64> byte_data_; + std::deque<uint64> packet_data_; + std::deque<base::TimeTicks> time_data_; +}; + +ByteCounter in_pipe_input_counter; +ByteCounter in_pipe_output_counter; +ByteCounter out_pipe_input_counter; +ByteCounter out_pipe_output_counter; + +class ByteCounterPipe : public media::cast::test::PacketPipe { + public: + ByteCounterPipe(ByteCounter* counter) : counter_(counter) {} + virtual void Send(scoped_ptr<media::cast::transport::Packet> packet) + OVERRIDE { + counter_->Increment(packet->size()); + pipe_->Send(packet.Pass()); + } + private: + ByteCounter* counter_; +}; + +void SetupByteCounters(scoped_ptr<media::cast::test::PacketPipe>* pipe, + ByteCounter* pipe_input_counter, + ByteCounter* pipe_output_counter) { + media::cast::test::PacketPipe* new_pipe = + new ByteCounterPipe(pipe_input_counter); + new_pipe->AppendToPipe(pipe->Pass()); + new_pipe->AppendToPipe( + scoped_ptr<media::cast::test::PacketPipe>( + new ByteCounterPipe(pipe_output_counter)).Pass()); + pipe->reset(new_pipe); +} + +void CheckByteCounters() { + base::TimeTicks now = base::TimeTicks::Now(); + in_pipe_input_counter.push(now); + in_pipe_output_counter.push(now); + out_pipe_input_counter.push(now); + out_pipe_output_counter.push(now); + if ((now - last_printout).InSeconds() >= 5) { + fprintf(stderr, "Sending : %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n", + in_pipe_output_counter.megabits_per_second(), + in_pipe_input_counter.megabits_per_second(), + in_pipe_output_counter.packets_per_second(), + in_pipe_input_counter.packets_per_second()); + fprintf(stderr, "Receiving: %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n", + out_pipe_output_counter.megabits_per_second(), + out_pipe_input_counter.megabits_per_second(), + out_pipe_output_counter.packets_per_second(), + out_pipe_input_counter.packets_per_second()); + + last_printout = now; + } + base::MessageLoopProxy::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&CheckByteCounters), + base::TimeDelta::FromMilliseconds(100)); +} + int main(int argc, char** argv) { if (argc < 5) { fprintf(stderr, "Usage: udp_proxy <localport> <remotehost> <remoteport> <type>\n" - "Where type is one of: perfect, wifi, evil\n"); + "Where type is one of: perfect, wifi, bad, evil\n"); exit(1); } @@ -42,6 +144,9 @@ int main(int argc, char** argv) { } else if (network_type == "wifi") { in_pipe = media::cast::test::WifiNetwork().Pass(); out_pipe = media::cast::test::WifiNetwork().Pass(); + } else if (network_type == "bad") { + in_pipe = media::cast::test::BadNetwork().Pass(); + out_pipe = media::cast::test::BadNetwork().Pass(); } else if (network_type == "evil") { in_pipe = media::cast::test::EvilNetwork().Pass(); out_pipe = media::cast::test::EvilNetwork().Pass(); @@ -50,6 +155,10 @@ int main(int argc, char** argv) { exit(1); } + SetupByteCounters(&in_pipe, &in_pipe_input_counter, &in_pipe_output_counter); + SetupByteCounters( + &out_pipe, &out_pipe_input_counter, &out_pipe_output_counter); + printf("Press Ctrl-C when done.\n"); scoped_ptr<media::cast::test::UDPProxy> proxy( media::cast::test::UDPProxy::Create(local_endpoint, @@ -57,6 +166,9 @@ int main(int argc, char** argv) { in_pipe.Pass(), out_pipe.Pass(), NULL)); - base::MessageLoop().Run(); // Run forever. + base::MessageLoop message_loop; + last_printout = base::TimeTicks::Now(); + CheckByteCounters(); + message_loop.Run(); return 1; } |