Add explicit |forceOnlineSignin| to user pod status
[chromium-blink-merge.git] / media / cast / test / receiver.cc
blob0a833861d3a32f31567af194f48e376e9f9a85a1
1 // Copyright 2013 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 <algorithm>
6 #include <climits>
7 #include <cstdarg>
8 #include <cstdio>
9 #include <string>
11 #include "base/at_exit.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/threading/thread.h"
18 #include "base/time/default_tick_clock.h"
19 #include "media/base/video_frame.h"
20 #include "media/cast/cast_config.h"
21 #include "media/cast/cast_environment.h"
22 #include "media/cast/cast_receiver.h"
23 #include "media/cast/logging/logging_defines.h"
24 #include "media/cast/test/utility/input_helper.h"
25 #include "media/cast/transport/transport/udp_transport.h"
26 #include "net/base/net_util.h"
28 #if defined(OS_LINUX)
29 #include "media/cast/test/linux_output_window.h"
30 #endif // OS_LINUX
32 namespace media {
33 namespace cast {
34 // Settings chosen to match default sender settings.
35 #define DEFAULT_SEND_PORT "0"
36 #define DEFAULT_RECEIVE_PORT "2344"
37 #define DEFAULT_SEND_IP "0.0.0.0"
38 #define DEFAULT_RESTART "0"
39 #define DEFAULT_AUDIO_FEEDBACK_SSRC "1"
40 #define DEFAULT_AUDIO_INCOMING_SSRC "2"
41 #define DEFAULT_AUDIO_PAYLOAD_TYPE "127"
42 #define DEFAULT_VIDEO_FEEDBACK_SSRC "12"
43 #define DEFAULT_VIDEO_INCOMING_SSRC "11"
44 #define DEFAULT_VIDEO_PAYLOAD_TYPE "96"
45 #define DEFAULT_VIDEO_CODEC_WIDTH "640"
46 #define DEFAULT_VIDEO_CODEC_HEIGHT "480"
47 #define DEFAULT_VIDEO_CODEC_BITRATE "2000"
49 static const int kAudioSamplingFrequency = 48000;
50 #if defined(OS_LINUX)
51 const int kVideoWindowWidth = 1280;
52 const int kVideoWindowHeight = 720;
53 #endif // OS_LINUX
54 static const int kFrameTimerMs = 33;
57 void GetPorts(int* tx_port, int* rx_port) {
58 test::InputBuilder tx_input("Enter send port.",
59 DEFAULT_SEND_PORT, 1, INT_MAX);
60 *tx_port = tx_input.GetIntInput();
62 test::InputBuilder rx_input("Enter receive port.",
63 DEFAULT_RECEIVE_PORT, 1, INT_MAX);
64 *rx_port = rx_input.GetIntInput();
67 std::string GetIpAddress(const std::string display_text) {
68 test::InputBuilder input(display_text, DEFAULT_SEND_IP, INT_MIN, INT_MAX);
69 std::string ip_address = input.GetStringInput();
70 // Ensure IP address is either the default value or in correct form.
71 while (ip_address != DEFAULT_SEND_IP &&
72 std::count(ip_address.begin(), ip_address.end(), '.') != 3) {
73 ip_address = input.GetStringInput();
75 return ip_address;
78 void GetSsrcs(AudioReceiverConfig* audio_config) {
79 test::InputBuilder input_tx("Choose audio sender SSRC.",
80 DEFAULT_AUDIO_FEEDBACK_SSRC, 1, INT_MAX);
81 audio_config->feedback_ssrc = input_tx.GetIntInput();
83 test::InputBuilder input_rx("Choose audio receiver SSRC.",
84 DEFAULT_AUDIO_INCOMING_SSRC, 1, INT_MAX);
85 audio_config->incoming_ssrc = input_tx.GetIntInput();
88 void GetSsrcs(VideoReceiverConfig* video_config) {
89 test::InputBuilder input_tx("Choose video sender SSRC.",
90 DEFAULT_VIDEO_FEEDBACK_SSRC, 1, INT_MAX);
91 video_config->feedback_ssrc = input_tx.GetIntInput();
93 test::InputBuilder input_rx("Choose video receiver SSRC.",
94 DEFAULT_VIDEO_INCOMING_SSRC, 1, INT_MAX);
95 video_config->incoming_ssrc = input_rx.GetIntInput();
98 void GetPayloadtype(AudioReceiverConfig* audio_config) {
99 test::InputBuilder input("Choose audio receiver payload type.",
100 DEFAULT_AUDIO_PAYLOAD_TYPE, 96, 127);
101 audio_config->rtp_payload_type = input.GetIntInput();
104 AudioReceiverConfig GetAudioReceiverConfig() {
105 AudioReceiverConfig audio_config;
107 GetSsrcs(&audio_config);
108 GetPayloadtype(&audio_config);
110 audio_config.rtcp_c_name = "audio_receiver@a.b.c.d";
112 VLOG(1) << "Using OPUS 48Khz stereo";
113 audio_config.use_external_decoder = false;
114 audio_config.frequency = 48000;
115 audio_config.channels = 2;
116 audio_config.codec = transport::kOpus;
117 return audio_config;
120 void GetPayloadtype(VideoReceiverConfig* video_config) {
121 test::InputBuilder input("Choose video receiver payload type.",
122 DEFAULT_VIDEO_PAYLOAD_TYPE, 96, 127);
123 video_config->rtp_payload_type = input.GetIntInput();
126 VideoReceiverConfig GetVideoReceiverConfig() {
127 VideoReceiverConfig video_config;
129 GetSsrcs(&video_config);
130 GetPayloadtype(&video_config);
132 video_config.rtcp_c_name = "video_receiver@a.b.c.d";
134 video_config.use_external_decoder = false;
136 VLOG(1) << "Using VP8";
137 video_config.codec = transport::kVp8;
138 return video_config;
142 class ReceiveProcess : public base::RefCountedThreadSafe<ReceiveProcess> {
143 public:
144 explicit ReceiveProcess(scoped_refptr<FrameReceiver> frame_receiver)
145 : frame_receiver_(frame_receiver),
146 #if defined(OS_LINUX)
147 render_(0, 0, kVideoWindowWidth, kVideoWindowHeight, "Cast_receiver"),
148 #endif // OS_LINUX
149 last_playout_time_(),
150 last_render_time_() {}
152 void Start() {
153 GetAudioFrame(base::TimeDelta::FromMilliseconds(kFrameTimerMs));
154 GetVideoFrame();
157 protected:
158 virtual ~ReceiveProcess() {}
160 private:
161 friend class base::RefCountedThreadSafe<ReceiveProcess>;
163 void DisplayFrame(const scoped_refptr<media::VideoFrame>& video_frame,
164 const base::TimeTicks& render_time) {
165 #ifdef OS_LINUX
166 render_.RenderFrame(video_frame);
167 #endif // OS_LINUX
168 // Print out the delta between frames.
169 if (!last_render_time_.is_null()){
170 base::TimeDelta time_diff = render_time - last_render_time_;
171 VLOG(0) << " RenderDelay[mS] = " << time_diff.InMilliseconds();
173 last_render_time_ = render_time;
174 GetVideoFrame();
177 void ReceiveAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame,
178 const base::TimeTicks& playout_time) {
179 // For audio just print the playout delta between audio frames.
180 // Default diff time is kFrameTimerMs.
181 base::TimeDelta time_diff =
182 base::TimeDelta::FromMilliseconds(kFrameTimerMs);
183 if (!last_playout_time_.is_null()){
184 time_diff = playout_time - last_playout_time_;
185 VLOG(0) << " ***PlayoutDelay[mS] = " << time_diff.InMilliseconds();
187 last_playout_time_ = playout_time;
188 GetAudioFrame(time_diff);
191 void GetAudioFrame(base::TimeDelta playout_diff) {
192 int num_10ms_blocks = playout_diff.InMilliseconds() / 10;
193 frame_receiver_->GetRawAudioFrame(num_10ms_blocks, kAudioSamplingFrequency,
194 base::Bind(&ReceiveProcess::ReceiveAudioFrame, this));
197 void GetVideoFrame() {
198 frame_receiver_->GetRawVideoFrame(
199 base::Bind(&ReceiveProcess::DisplayFrame, this));
202 scoped_refptr<FrameReceiver> frame_receiver_;
203 #ifdef OS_LINUX
204 test::LinuxOutputWindow render_;
205 #endif // OS_LINUX
206 base::TimeTicks last_playout_time_;
207 base::TimeTicks last_render_time_;
210 } // namespace cast
211 } // namespace media
213 int main(int argc, char** argv) {
214 base::AtExitManager at_exit;
215 base::MessageLoopForIO main_message_loop;
216 CommandLine::Init(argc, argv);
217 InitLogging(logging::LoggingSettings());
219 VLOG(1) << "Cast Receiver";
220 base::Thread audio_thread("Cast audio decoder thread");
221 base::Thread video_thread("Cast video decoder thread");
222 audio_thread.Start();
223 video_thread.Start();
225 base::DefaultTickClock clock;
226 // Enable receiver side threads, and disable logging.
227 scoped_refptr<media::cast::CastEnvironment> cast_environment(new
228 media::cast::CastEnvironment(&clock,
229 main_message_loop.message_loop_proxy(),
230 NULL,
231 audio_thread.message_loop_proxy(),
232 NULL,
233 video_thread.message_loop_proxy(),
234 main_message_loop.message_loop_proxy(),
235 media::cast::GetDefaultCastLoggingConfig()));
237 media::cast::AudioReceiverConfig audio_config =
238 media::cast::GetAudioReceiverConfig();
239 media::cast::VideoReceiverConfig video_config =
240 media::cast::GetVideoReceiverConfig();
242 int remote_port, local_port;
243 media::cast::GetPorts(&remote_port, &local_port);
244 if (!local_port) {
245 LOG(ERROR) << "Invalid local port.";
246 return 1;
249 std::string remote_ip_address = media::cast::GetIpAddress("Enter remote IP.");
250 std::string local_ip_address = media::cast::GetIpAddress("Enter local IP.");
251 net::IPAddressNumber remote_ip_number;
252 net::IPAddressNumber local_ip_number;
254 if (!net::ParseIPLiteralToNumber(remote_ip_address, &remote_ip_number)) {
255 LOG(ERROR) << "Invalid remote IP address.";
256 return 1;
259 if (!net::ParseIPLiteralToNumber(local_ip_address, &local_ip_number)) {
260 LOG(ERROR) << "Invalid local IP address.";
261 return 1;
264 net::IPEndPoint remote_end_point(remote_ip_number, remote_port);
265 net::IPEndPoint local_end_point(local_ip_number, local_port);
267 scoped_ptr<media::cast::transport::UdpTransport> transport(
268 new media::cast::transport::UdpTransport(
269 main_message_loop.message_loop_proxy(),
270 local_end_point,
271 remote_end_point));
272 scoped_ptr<media::cast::CastReceiver> cast_receiver(
273 media::cast::CastReceiver::CreateCastReceiver(
274 cast_environment,
275 audio_config,
276 video_config,
277 transport.get()));
279 media::cast::transport::PacketReceiver* packet_receiver =
280 cast_receiver->packet_receiver();
282 transport->StartReceiving(packet_receiver);
284 scoped_refptr<media::cast::ReceiveProcess> receive_process(
285 new media::cast::ReceiveProcess(cast_receiver->frame_receiver()));
286 receive_process->Start();
287 main_message_loop.Run();
288 return 0;