Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / cast / test / utility / udp_proxy_main.cc
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.
4
5 #include <cstdio>
6 #include <cstdlib>
7 #include <deque>
8 #include <string>
9
10 #include "base/at_exit.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h"
15 #include "media/cast/test/utility/udp_proxy.h"
16
17 base::TimeTicks last_printout;
18
19 class ByteCounter {
20  public:
21   ByteCounter() : bytes_(0), packets_(0) {
22     push(base::TimeTicks::Now());
23   }
24
25   base::TimeDelta time_range() {
26     return time_data_.back() - time_data_.front();
27   }
28
29   void push(base::TimeTicks now) {
30     byte_data_.push_back(bytes_);
31     packet_data_.push_back(packets_);
32     time_data_.push_back(now);
33     while (time_range().InSeconds() > 10) {
34       byte_data_.pop_front();
35       packet_data_.pop_front();
36       time_data_.pop_front();
37     }
38   }
39
40   double megabits_per_second() {
41     double megabits = (byte_data_.back() - byte_data_.front()) * 8 / 1E6;
42     return megabits / time_range().InSecondsF();
43   }
44
45   double packets_per_second() {
46     double packets = packet_data_.back()- packet_data_.front();
47     return packets / time_range().InSecondsF();
48   }
49
50   void Increment(uint64 x) {
51     bytes_ += x;
52     packets_ ++;
53   }
54
55  private:
56   uint64 bytes_;
57   uint64 packets_;
58   std::deque<uint64> byte_data_;
59   std::deque<uint64> packet_data_;
60   std::deque<base::TimeTicks> time_data_;
61 };
62
63 ByteCounter in_pipe_input_counter;
64 ByteCounter in_pipe_output_counter;
65 ByteCounter out_pipe_input_counter;
66 ByteCounter out_pipe_output_counter;
67
68 class ByteCounterPipe : public media::cast::test::PacketPipe {
69  public:
70   ByteCounterPipe(ByteCounter* counter) : counter_(counter) {}
71   virtual void Send(scoped_ptr<media::cast::transport::Packet> packet)
72       OVERRIDE {
73     counter_->Increment(packet->size());
74     pipe_->Send(packet.Pass());
75   }
76  private:
77   ByteCounter* counter_;
78 };
79
80 void SetupByteCounters(scoped_ptr<media::cast::test::PacketPipe>* pipe,
81                        ByteCounter* pipe_input_counter,
82                        ByteCounter* pipe_output_counter) {
83   media::cast::test::PacketPipe* new_pipe =
84       new ByteCounterPipe(pipe_input_counter);
85   new_pipe->AppendToPipe(pipe->Pass());
86   new_pipe->AppendToPipe(
87       scoped_ptr<media::cast::test::PacketPipe>(
88           new ByteCounterPipe(pipe_output_counter)).Pass());
89   pipe->reset(new_pipe);
90 }
91
92 void CheckByteCounters() {
93   base::TimeTicks now = base::TimeTicks::Now();
94   in_pipe_input_counter.push(now);
95   in_pipe_output_counter.push(now);
96   out_pipe_input_counter.push(now);
97   out_pipe_output_counter.push(now);
98   if ((now - last_printout).InSeconds() >= 5) {
99     fprintf(stderr, "Sending  : %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n",
100             in_pipe_output_counter.megabits_per_second(),
101             in_pipe_input_counter.megabits_per_second(),
102             in_pipe_output_counter.packets_per_second(),
103             in_pipe_input_counter.packets_per_second());
104     fprintf(stderr, "Receiving: %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n",
105             out_pipe_output_counter.megabits_per_second(),
106             out_pipe_input_counter.megabits_per_second(),
107             out_pipe_output_counter.packets_per_second(),
108             out_pipe_input_counter.packets_per_second());
109
110     last_printout = now;
111   }
112   base::MessageLoopProxy::current()->PostDelayedTask(
113       FROM_HERE,
114       base::Bind(&CheckByteCounters),
115       base::TimeDelta::FromMilliseconds(100));
116 }
117
118 int main(int argc, char** argv) {
119   if (argc < 5) {
120     fprintf(stderr,
121             "Usage: udp_proxy <localport> <remotehost> <remoteport> <type>\n"
122             "Where type is one of: perfect, wifi, bad, evil\n");
123     exit(1);
124   }
125
126   base::AtExitManager exit_manager;
127   CommandLine::Init(argc, argv);
128   InitLogging(logging::LoggingSettings());
129
130   int local_port = atoi(argv[1]);
131   int remote_port = atoi(argv[3]);
132   net::IPAddressNumber remote_ip_number;
133   net::IPAddressNumber local_ip_number;
134
135   CHECK(net::ParseIPLiteralToNumber(argv[2], &remote_ip_number));
136   CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &local_ip_number));
137   net::IPEndPoint remote_endpoint(remote_ip_number, remote_port);
138   net::IPEndPoint local_endpoint(local_ip_number, local_port);
139
140   scoped_ptr<media::cast::test::PacketPipe> in_pipe, out_pipe;
141   std::string network_type = argv[4];
142   if (network_type == "perfect") {
143     // No action needed.
144   } else if (network_type == "wifi") {
145     in_pipe = media::cast::test::WifiNetwork().Pass();
146     out_pipe = media::cast::test::WifiNetwork().Pass();
147   } else if (network_type == "bad") {
148     in_pipe = media::cast::test::BadNetwork().Pass();
149     out_pipe = media::cast::test::BadNetwork().Pass();
150   } else if (network_type == "evil") {
151     in_pipe = media::cast::test::EvilNetwork().Pass();
152     out_pipe = media::cast::test::EvilNetwork().Pass();
153   } else {
154     fprintf(stderr, "Unknown network type.\n");
155     exit(1);
156   }
157
158   SetupByteCounters(&in_pipe, &in_pipe_input_counter, &in_pipe_output_counter);
159   SetupByteCounters(
160       &out_pipe, &out_pipe_input_counter, &out_pipe_output_counter);
161
162   printf("Press Ctrl-C when done.\n");
163   scoped_ptr<media::cast::test::UDPProxy> proxy(
164       media::cast::test::UDPProxy::Create(local_endpoint,
165                                           remote_endpoint,
166                                           in_pipe.Pass(),
167                                           out_pipe.Pass(),
168                                           NULL));
169   base::MessageLoop message_loop;
170   last_printout = base::TimeTicks::Now();
171   CheckByteCounters();
172   message_loop.Run();
173   return 1;
174 }