Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / media / cast / test / utility / udp_proxy_main.cc
blob439b079747786ca9e6d42be3f60e8875dfc0363f
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
3 // found in the LICENSE file.
5 #include <cstdio>
6 #include <cstdlib>
7 #include <deque>
8 #include <string>
10 #include "base/at_exit.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/lazy_instance.h"
14 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "media/cast/test/utility/udp_proxy.h"
20 class ByteCounter {
21 public:
22 ByteCounter() : bytes_(0), packets_(0) {
23 push(base::TimeTicks::Now());
26 base::TimeDelta time_range() {
27 return time_data_.back() - time_data_.front();
30 void push(base::TimeTicks now) {
31 byte_data_.push_back(bytes_);
32 packet_data_.push_back(packets_);
33 time_data_.push_back(now);
34 while (time_range().InSeconds() > 10) {
35 byte_data_.pop_front();
36 packet_data_.pop_front();
37 time_data_.pop_front();
41 double megabits_per_second() {
42 double megabits = (byte_data_.back() - byte_data_.front()) * 8 / 1E6;
43 return megabits / time_range().InSecondsF();
46 double packets_per_second() {
47 double packets = packet_data_.back()- packet_data_.front();
48 return packets / time_range().InSecondsF();
51 void Increment(uint64 x) {
52 bytes_ += x;
53 packets_ ++;
56 private:
57 uint64 bytes_;
58 uint64 packets_;
59 std::deque<uint64> byte_data_;
60 std::deque<uint64> packet_data_;
61 std::deque<base::TimeTicks> time_data_;
64 namespace {
65 struct GlobalCounter {
66 base::TimeTicks last_printout;
67 ByteCounter in_pipe_input_counter;
68 ByteCounter in_pipe_output_counter;
69 ByteCounter out_pipe_input_counter;
70 ByteCounter out_pipe_output_counter;
72 } // namespace
74 base::LazyInstance<GlobalCounter>::Leaky g_counter =
75 LAZY_INSTANCE_INITIALIZER;
77 class ByteCounterPipe : public media::cast::test::PacketPipe {
78 public:
79 ByteCounterPipe(ByteCounter* counter) : counter_(counter) {}
80 void Send(scoped_ptr<media::cast::Packet> packet) final {
81 counter_->Increment(packet->size());
82 pipe_->Send(packet.Pass());
84 private:
85 ByteCounter* counter_;
88 void SetupByteCounters(scoped_ptr<media::cast::test::PacketPipe>* pipe,
89 ByteCounter* pipe_input_counter,
90 ByteCounter* pipe_output_counter) {
91 media::cast::test::PacketPipe* new_pipe =
92 new ByteCounterPipe(pipe_input_counter);
93 new_pipe->AppendToPipe(pipe->Pass());
94 new_pipe->AppendToPipe(
95 scoped_ptr<media::cast::test::PacketPipe>(
96 new ByteCounterPipe(pipe_output_counter)).Pass());
97 pipe->reset(new_pipe);
100 void CheckByteCounters() {
101 base::TimeTicks now = base::TimeTicks::Now();
102 g_counter.Get().in_pipe_input_counter.push(now);
103 g_counter.Get().in_pipe_output_counter.push(now);
104 g_counter.Get().out_pipe_input_counter.push(now);
105 g_counter.Get().out_pipe_output_counter.push(now);
106 if ((now - g_counter.Get().last_printout).InSeconds() >= 5) {
107 fprintf(stderr, "Sending : %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n",
108 g_counter.Get().in_pipe_output_counter.megabits_per_second(),
109 g_counter.Get().in_pipe_input_counter.megabits_per_second(),
110 g_counter.Get().in_pipe_output_counter.packets_per_second(),
111 g_counter.Get().in_pipe_input_counter.packets_per_second());
112 fprintf(stderr, "Receiving: %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n",
113 g_counter.Get().out_pipe_output_counter.megabits_per_second(),
114 g_counter.Get().out_pipe_input_counter.megabits_per_second(),
115 g_counter.Get().out_pipe_output_counter.packets_per_second(),
116 g_counter.Get().out_pipe_input_counter.packets_per_second());
118 g_counter.Get().last_printout = now;
120 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
121 FROM_HERE,
122 base::Bind(&CheckByteCounters),
123 base::TimeDelta::FromMilliseconds(100));
126 int main(int argc, char** argv) {
127 base::AtExitManager at_exit;
128 base::CommandLine::Init(argc, argv);
129 logging::LoggingSettings settings;
130 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
131 InitLogging(settings);
133 if (argc != 5 && argc != 3) {
134 fprintf(stderr,
135 "Usage: udp_proxy <localport> <remotehost> <remoteport> <type>\n"
136 "or:\n"
137 " udp_proxy <localport> <type>\n"
138 "Where type is one of: perfect, wifi, bad, evil, poisson-wifi\n");
139 exit(1);
142 net::IPAddressNumber remote_ip_number;
143 net::IPAddressNumber local_ip_number;
144 std::string network_type;
145 int local_port = atoi(argv[1]);
146 int remote_port = 0;
147 CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &local_ip_number));
149 if (argc == 5) {
150 // V2 proxy
151 CHECK(net::ParseIPLiteralToNumber(argv[2], &remote_ip_number));
152 remote_port = atoi(argv[3]);
153 network_type = argv[4];
154 } else {
155 // V1 proxy
156 network_type = argv[2];
158 if (local_port < 0 || local_port > 65535 || remote_port < 0 ||
159 remote_port > 65535) {
160 fprintf(stderr, "Port numbers must be between 0 and 65535\n");
161 exit(1);
163 net::IPEndPoint remote_endpoint(remote_ip_number,
164 static_cast<uint16>(remote_port));
165 net::IPEndPoint local_endpoint(local_ip_number,
166 static_cast<uint16>(local_port));
167 scoped_ptr<media::cast::test::PacketPipe> in_pipe, out_pipe;
168 scoped_ptr<media::cast::test::InterruptedPoissonProcess> ipp(
169 media::cast::test::DefaultInterruptedPoissonProcess());
171 if (network_type == "perfect") {
172 // No action needed.
173 } else if (network_type == "wifi") {
174 in_pipe = media::cast::test::WifiNetwork().Pass();
175 out_pipe = media::cast::test::WifiNetwork().Pass();
176 } else if (network_type == "bad") {
177 in_pipe = media::cast::test::BadNetwork().Pass();
178 out_pipe = media::cast::test::BadNetwork().Pass();
179 } else if (network_type == "evil") {
180 in_pipe = media::cast::test::EvilNetwork().Pass();
181 out_pipe = media::cast::test::EvilNetwork().Pass();
182 } else if (network_type == "poisson-wifi") {
183 in_pipe = ipp->NewBuffer(128 * 1024).Pass();
184 out_pipe = ipp->NewBuffer(128 * 1024).Pass();
185 } else {
186 fprintf(stderr, "Unknown network type.\n");
187 exit(1);
190 SetupByteCounters(&in_pipe, &(g_counter.Get().in_pipe_input_counter),
191 &(g_counter.Get().in_pipe_output_counter));
192 SetupByteCounters(
193 &out_pipe, &(g_counter.Get().out_pipe_input_counter),
194 &(g_counter.Get().out_pipe_output_counter));
196 printf("Press Ctrl-C when done.\n");
197 scoped_ptr<media::cast::test::UDPProxy> proxy(
198 media::cast::test::UDPProxy::Create(local_endpoint,
199 remote_endpoint,
200 in_pipe.Pass(),
201 out_pipe.Pass(),
202 NULL));
203 base::MessageLoop message_loop;
204 g_counter.Get().last_printout = base::TimeTicks::Now();
205 CheckByteCounters();
206 message_loop.Run();
207 return 1;