Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: remoting/test/protocol_perftest.cc

Issue 1642793002: Add performance test for WebRTC protocol. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@client_webrtc_support
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/test/fake_socket_factory.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <utility> 5 #include <utility>
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/rand_util.h" 11 #include "base/rand_util.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "base/task_runner_util.h"
15 #include "base/thread_task_runner_handle.h" 16 #include "base/thread_task_runner_handle.h"
16 #include "jingle/glue/thread_wrapper.h" 17 #include "jingle/glue/thread_wrapper.h"
17 #include "net/base/test_data_directory.h" 18 #include "net/base/test_data_directory.h"
18 #include "net/url_request/url_request_context_getter.h" 19 #include "net/url_request/url_request_context_getter.h"
19 #include "remoting/base/rsa_key_pair.h" 20 #include "remoting/base/rsa_key_pair.h"
20 #include "remoting/client/audio_player.h" 21 #include "remoting/client/audio_player.h"
21 #include "remoting/client/chromoting_client.h" 22 #include "remoting/client/chromoting_client.h"
22 #include "remoting/client/client_context.h" 23 #include "remoting/client/client_context.h"
23 #include "remoting/client/client_user_interface.h" 24 #include "remoting/client/client_user_interface.h"
25 #include "remoting/codec/video_decoder_verbatim.h"
26 #include "remoting/codec/video_decoder_vpx.h"
24 #include "remoting/host/chromoting_host.h" 27 #include "remoting/host/chromoting_host.h"
25 #include "remoting/host/chromoting_host_context.h" 28 #include "remoting/host/chromoting_host_context.h"
26 #include "remoting/host/fake_desktop_environment.h" 29 #include "remoting/host/fake_desktop_environment.h"
30 #include "remoting/protocol/frame_consumer.h"
27 #include "remoting/protocol/jingle_session_manager.h" 31 #include "remoting/protocol/jingle_session_manager.h"
28 #include "remoting/protocol/me2me_host_authenticator_factory.h" 32 #include "remoting/protocol/me2me_host_authenticator_factory.h"
29 #include "remoting/protocol/negotiating_client_authenticator.h" 33 #include "remoting/protocol/negotiating_client_authenticator.h"
30 #include "remoting/protocol/session_config.h" 34 #include "remoting/protocol/session_config.h"
31 #include "remoting/protocol/transport_context.h" 35 #include "remoting/protocol/transport_context.h"
32 #include "remoting/protocol/video_frame_pump.h" 36 #include "remoting/protocol/video_frame_pump.h"
33 #include "remoting/protocol/video_renderer.h" 37 #include "remoting/protocol/video_renderer.h"
34 #include "remoting/signaling/fake_signal_strategy.h" 38 #include "remoting/signaling/fake_signal_strategy.h"
39 #include "remoting/test/cyclic_frame_generator.h"
35 #include "remoting/test/fake_network_dispatcher.h" 40 #include "remoting/test/fake_network_dispatcher.h"
36 #include "remoting/test/fake_port_allocator.h" 41 #include "remoting/test/fake_port_allocator.h"
37 #include "remoting/test/fake_socket_factory.h" 42 #include "remoting/test/fake_socket_factory.h"
38 #include "testing/gtest/include/gtest/gtest.h" 43 #include "testing/gtest/include/gtest/gtest.h"
39 44
40 namespace remoting { 45 namespace remoting {
41 46
42 using protocol::ChannelConfig; 47 using protocol::ChannelConfig;
43 48
49 namespace {
50
44 const char kHostJid[] = "host_jid@example.com/host"; 51 const char kHostJid[] = "host_jid@example.com/host";
45 const char kHostOwner[] = "jane.doe@example.com"; 52 const char kHostOwner[] = "jane.doe@example.com";
46 const char kClientJid[] = "jane.doe@example.com/client"; 53 const char kClientJid[] = "jane.doe@example.com/client";
47 54
48 struct NetworkPerformanceParams { 55 struct NetworkPerformanceParams {
49 NetworkPerformanceParams(int bandwidth, 56 NetworkPerformanceParams(int bandwidth,
50 int max_buffers, 57 int max_buffers,
51 double latency_average_ms, 58 double latency_average_ms,
52 double latency_stddev_ms, 59 double latency_stddev_ms,
53 double out_of_order_rate) 60 double out_of_order_rate)
(...skipping 12 matching lines...) Expand all
66 73
67 class FakeCursorShapeStub : public protocol::CursorShapeStub { 74 class FakeCursorShapeStub : public protocol::CursorShapeStub {
68 public: 75 public:
69 FakeCursorShapeStub() {} 76 FakeCursorShapeStub() {}
70 ~FakeCursorShapeStub() override {} 77 ~FakeCursorShapeStub() override {}
71 78
72 // protocol::CursorShapeStub interface. 79 // protocol::CursorShapeStub interface.
73 void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override{}; 80 void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override{};
74 }; 81 };
75 82
83 scoped_ptr<webrtc::DesktopFrame> DoDecodeFrame(
84 VideoDecoder* decoder,
85 VideoPacket* packet,
86 scoped_ptr<webrtc::DesktopFrame> frame) {
87 if (!decoder->DecodePacket(*packet, frame.get()))
88 frame.reset();
89 return frame;
90 }
91
92 } // namespace
93
76 class ProtocolPerfTest 94 class ProtocolPerfTest
77 : public testing::Test, 95 : public testing::Test,
78 public testing::WithParamInterface<NetworkPerformanceParams>, 96 public testing::WithParamInterface<NetworkPerformanceParams>,
79 public ClientUserInterface, 97 public ClientUserInterface,
80 public protocol::VideoRenderer, 98 public protocol::VideoRenderer,
81 public protocol::VideoStub, 99 public protocol::VideoStub,
100 public protocol::FrameConsumer,
82 public HostStatusObserver { 101 public HostStatusObserver {
83 public: 102 public:
84 ProtocolPerfTest() 103 ProtocolPerfTest()
85 : host_thread_("host"), 104 : host_thread_("host"),
86 capture_thread_("capture"), 105 capture_thread_("capture"),
87 encode_thread_("encode") { 106 encode_thread_("encode"),
107 decode_thread_("decode") {
88 protocol::VideoFramePump::EnableTimestampsForTests(); 108 protocol::VideoFramePump::EnableTimestampsForTests();
89 host_thread_.StartWithOptions( 109 host_thread_.StartWithOptions(
90 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 110 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
91 capture_thread_.Start(); 111 capture_thread_.Start();
92 encode_thread_.Start(); 112 encode_thread_.Start();
113 decode_thread_.Start();
93 } 114 }
94 115
95 virtual ~ProtocolPerfTest() { 116 virtual ~ProtocolPerfTest() {
96 host_thread_.task_runner()->DeleteSoon(FROM_HERE, host_.release()); 117 host_thread_.task_runner()->DeleteSoon(FROM_HERE, host_.release());
97 host_thread_.task_runner()->DeleteSoon(FROM_HERE, 118 host_thread_.task_runner()->DeleteSoon(FROM_HERE,
98 host_signaling_.release()); 119 host_signaling_.release());
99 message_loop_.RunUntilIdle(); 120 message_loop_.RunUntilIdle();
100 } 121 }
101 122
102 // ClientUserInterface interface. 123 // ClientUserInterface interface.
(...skipping 13 matching lines...) Expand all
116 const protocol::PairingResponse& pairing_response) override {} 137 const protocol::PairingResponse& pairing_response) override {}
117 void DeliverHostMessage(const protocol::ExtensionMessage& message) override {} 138 void DeliverHostMessage(const protocol::ExtensionMessage& message) override {}
118 protocol::ClipboardStub* GetClipboardStub() override { return nullptr; } 139 protocol::ClipboardStub* GetClipboardStub() override { return nullptr; }
119 protocol::CursorShapeStub* GetCursorShapeStub() override { 140 protocol::CursorShapeStub* GetCursorShapeStub() override {
120 return &cursor_shape_stub_; 141 return &cursor_shape_stub_;
121 } 142 }
122 143
123 // VideoRenderer interface. 144 // VideoRenderer interface.
124 void OnSessionConfig(const protocol::SessionConfig& config) override {} 145 void OnSessionConfig(const protocol::SessionConfig& config) override {}
125 protocol::VideoStub* GetVideoStub() override { return this; } 146 protocol::VideoStub* GetVideoStub() override { return this; }
126 protocol::FrameConsumer* GetFrameConsumer() override { 147 protocol::FrameConsumer* GetFrameConsumer() override { return this; }
127 NOTREACHED();
128 return nullptr;
129 }
130 148
131 // protocol::VideoStub interface. 149 // protocol::VideoStub interface.
132 void ProcessVideoPacket(scoped_ptr<VideoPacket> video_packet, 150 void ProcessVideoPacket(scoped_ptr<VideoPacket> packet,
133 const base::Closure& done) override { 151 const base::Closure& done) override {
134 if (video_packet->data().empty()) { 152 if (packet->data().empty()) {
135 // Ignore keep-alive packets 153 // Ignore keep-alive packets
136 done.Run(); 154 done.Run();
137 return; 155 return;
138 } 156 }
139 157
140 last_video_packet_ = std::move(video_packet); 158 if (packet->format().has_screen_width() &&
159 packet->format().has_screen_height()) {
160 frame_size_.set(packet->format().screen_width(),
161 packet->format().screen_height());
162 }
141 163
164 scoped_ptr<webrtc::DesktopFrame> frame(
165 new webrtc::BasicDesktopFrame(frame_size_));
166 base::PostTaskAndReplyWithResult(
167 decode_thread_.task_runner().get(), FROM_HERE,
168 base::Bind(&DoDecodeFrame, video_decoder_.get(), packet.get(),
169 base::Passed(&frame)),
170 base::Bind(&ProtocolPerfTest::OnFrameDecoded, base::Unretained(this),
171 base::Passed(&packet), done));
172 }
173
174 void OnFrameDecoded(scoped_ptr<VideoPacket> packet,
175 const base::Closure& done,
176 scoped_ptr<webrtc::DesktopFrame> frame) {
177 last_video_packet_ = std::move(packet);
178 DrawFrame(std::move(frame), done);
179 }
180
181 // protocol::FrameConsumer interface.
182 scoped_ptr<webrtc::DesktopFrame> AllocateFrame(
183 const webrtc::DesktopSize& size) override {
184 return make_scoped_ptr(new webrtc::BasicDesktopFrame(size));
185 }
186
187 void DrawFrame(scoped_ptr<webrtc::DesktopFrame> frame,
188 const base::Closure& done) override {
189 last_video_frame_ = std::move(frame);
142 if (!on_frame_task_.is_null()) 190 if (!on_frame_task_.is_null())
143 on_frame_task_.Run(); 191 on_frame_task_.Run();
192 if (!done.is_null())
193 done.Run();
194 }
144 195
145 done.Run(); 196 protocol::FrameConsumer::PixelFormat GetPixelFormat() override {
197 return FORMAT_BGRA;
146 } 198 }
147 199
148 // HostStatusObserver interface. 200 // HostStatusObserver interface.
149 void OnClientConnected(const std::string& jid) override { 201 void OnClientConnected(const std::string& jid) override {
150 message_loop_.PostTask( 202 message_loop_.PostTask(
151 FROM_HERE, 203 FROM_HERE,
152 base::Bind(&ProtocolPerfTest::OnHostConnectedMainThread, 204 base::Bind(&ProtocolPerfTest::OnHostConnectedMainThread,
153 base::Unretained(this))); 205 base::Unretained(this)));
154 } 206 }
155 207
156 protected: 208 protected:
157 void WaitConnected() { 209 void WaitConnected() {
158 client_connected_ = false; 210 client_connected_ = false;
159 host_connected_ = false; 211 host_connected_ = false;
160 212
161 connecting_loop_.reset(new base::RunLoop()); 213 connecting_loop_.reset(new base::RunLoop());
162 connecting_loop_->Run(); 214 connecting_loop_->Run();
163 215
164 ASSERT_TRUE(client_connected_ && host_connected_); 216 ASSERT_TRUE(client_connected_ && host_connected_);
165 } 217 }
166 218
167 void OnHostConnectedMainThread() { 219 void OnHostConnectedMainThread() {
168 host_connected_ = true; 220 host_connected_ = true;
169 if (client_connected_) 221 if (client_connected_)
170 connecting_loop_->Quit(); 222 connecting_loop_->Quit();
171 } 223 }
172 224
173 void ReceiveFrame(base::TimeDelta* latency) { 225 scoped_ptr<webrtc::DesktopFrame> ReceiveFrame() {
226 last_video_frame_.reset();
227
174 waiting_frames_loop_.reset(new base::RunLoop()); 228 waiting_frames_loop_.reset(new base::RunLoop());
175 on_frame_task_ = waiting_frames_loop_->QuitClosure(); 229 on_frame_task_ = waiting_frames_loop_->QuitClosure();
176 waiting_frames_loop_->Run(); 230 waiting_frames_loop_->Run();
177 231
232 EXPECT_TRUE(last_video_frame_);
233 return std::move(last_video_frame_);
234 }
235
236 void ReceiveFrameAndGetLatency(base::TimeDelta* latency) {
237 last_video_packet_.reset();
238
239 ReceiveFrame();
240
178 if (latency) { 241 if (latency) {
179 base::TimeTicks timestamp = 242 base::TimeTicks timestamp =
180 base::TimeTicks::FromInternalValue(last_video_packet_->timestamp()); 243 base::TimeTicks::FromInternalValue(last_video_packet_->timestamp());
181 *latency = base::TimeTicks::Now() - timestamp; 244 *latency = base::TimeTicks::Now() - timestamp;
182 } 245 }
183 } 246 }
184 247
185 void ReceiveFrames(int frames, base::TimeDelta* max_latency) { 248 void ReceiveMultipleFramesAndGetMaxLatency(int frames,
249 base::TimeDelta* max_latency) {
186 if (max_latency) 250 if (max_latency)
187 *max_latency = base::TimeDelta(); 251 *max_latency = base::TimeDelta();
188 252
189 for (int i = 0; i < frames; ++i) { 253 for (int i = 0; i < frames; ++i) {
190 base::TimeDelta latency; 254 base::TimeDelta latency;
191 255
192 ReceiveFrame(&latency); 256 ReceiveFrameAndGetLatency(&latency);
193 257
194 if (max_latency && latency > *max_latency) { 258 if (max_latency && latency > *max_latency) {
195 *max_latency = latency; 259 *max_latency = latency;
196 } 260 }
197 } 261 }
198 } 262 }
199 263
200 // Creates test host and client and starts connection between them. Caller 264 // Creates test host and client and starts connection between them. Caller
201 // should call WaitConnected() to wait until connection is established. The 265 // should call WaitConnected() to wait until connection is established. The
202 // host is started on |host_thread_| while the client works on the main 266 // host is started on |host_thread_| while the client works on the main
203 // thread. 267 // thread.
204 void StartHostAndClient(protocol::ChannelConfig::Codec video_codec) { 268 void StartHostAndClient(bool use_webrtc,
269 protocol::ChannelConfig::Codec video_codec) {
205 fake_network_dispatcher_ = new FakeNetworkDispatcher(); 270 fake_network_dispatcher_ = new FakeNetworkDispatcher();
206 271
207 client_signaling_.reset(new FakeSignalStrategy(kClientJid)); 272 client_signaling_.reset(new FakeSignalStrategy(kClientJid));
208 273
209 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); 274 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
210 275
211 protocol_config_ = protocol::CandidateSessionConfig::CreateDefault(); 276 protocol_config_ = protocol::CandidateSessionConfig::CreateDefault();
212 protocol_config_->DisableAudioChannel(); 277 protocol_config_->DisableAudioChannel();
213 protocol_config_->mutable_video_configs()->clear(); 278 protocol_config_->mutable_video_configs()->clear();
214 protocol_config_->mutable_video_configs()->push_back( 279 protocol_config_->mutable_video_configs()->push_back(
215 protocol::ChannelConfig( 280 protocol::ChannelConfig(
216 protocol::ChannelConfig::TRANSPORT_STREAM, 2, video_codec)); 281 protocol::ChannelConfig::TRANSPORT_STREAM, 2, video_codec));
282 protocol_config_->set_webrtc_supported(use_webrtc);
283 protocol_config_->set_ice_supported(!use_webrtc);
284
285 switch (video_codec) {
286 case ChannelConfig::CODEC_VERBATIM:
287 video_decoder_.reset(new VideoDecoderVerbatim());
288 break;
289 case ChannelConfig::CODEC_VP8:
290 video_decoder_ = VideoDecoderVpx::CreateForVP8();
291 break;
292 default:
293 NOTREACHED();
294 }
217 295
218 host_thread_.task_runner()->PostTask( 296 host_thread_.task_runner()->PostTask(
219 FROM_HERE, 297 FROM_HERE,
220 base::Bind(&ProtocolPerfTest::StartHost, base::Unretained(this))); 298 base::Bind(&ProtocolPerfTest::StartHost, base::Unretained(this)));
221 } 299 }
222 300
223 void StartHost() { 301 void StartHost() {
224 DCHECK(host_thread_.task_runner()->BelongsToCurrentThread()); 302 DCHECK(host_thread_.task_runner()->BelongsToCurrentThread());
225 303
226 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); 304 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 new FakePortAllocatorFactory(fake_network_dispatcher_)); 378 new FakePortAllocatorFactory(fake_network_dispatcher_));
301 port_allocator_factory->socket_factory()->SetBandwidth( 379 port_allocator_factory->socket_factory()->SetBandwidth(
302 GetParam().bandwidth, GetParam().max_buffers); 380 GetParam().bandwidth, GetParam().max_buffers);
303 port_allocator_factory->socket_factory()->SetLatency( 381 port_allocator_factory->socket_factory()->SetLatency(
304 GetParam().latency_average, GetParam().latency_stddev); 382 GetParam().latency_average, GetParam().latency_stddev);
305 port_allocator_factory->socket_factory()->set_out_of_order_rate( 383 port_allocator_factory->socket_factory()->set_out_of_order_rate(
306 GetParam().out_of_order_rate); 384 GetParam().out_of_order_rate);
307 scoped_refptr<protocol::TransportContext> transport_context( 385 scoped_refptr<protocol::TransportContext> transport_context(
308 new protocol::TransportContext( 386 new protocol::TransportContext(
309 host_signaling_.get(), std::move(port_allocator_factory), 387 host_signaling_.get(), std::move(port_allocator_factory),
310 network_settings, protocol::TransportRole::SERVER)); 388 network_settings, protocol::TransportRole::CLIENT));
311 389
312 std::vector<protocol::AuthenticationMethod> auth_methods; 390 std::vector<protocol::AuthenticationMethod> auth_methods;
313 auth_methods.push_back(protocol::AuthenticationMethod::Spake2( 391 auth_methods.push_back(protocol::AuthenticationMethod::Spake2(
314 protocol::AuthenticationMethod::NONE)); 392 protocol::AuthenticationMethod::NONE));
315 scoped_ptr<protocol::Authenticator> client_authenticator( 393 scoped_ptr<protocol::Authenticator> client_authenticator(
316 new protocol::NegotiatingClientAuthenticator( 394 new protocol::NegotiatingClientAuthenticator(
317 std::string(), // client_pairing_id 395 std::string(), // client_pairing_id
318 std::string(), // client_pairing_secret 396 std::string(), // client_pairing_secret
319 std::string(), // authentication_tag 397 std::string(), // authentication_tag
320 base::Bind(&ProtocolPerfTest::FetchPin, base::Unretained(this)), 398 base::Bind(&ProtocolPerfTest::FetchPin, base::Unretained(this)),
321 nullptr, auth_methods)); 399 nullptr, auth_methods));
322 client_.reset( 400 client_.reset(
323 new ChromotingClient(client_context_.get(), this, this, nullptr)); 401 new ChromotingClient(client_context_.get(), this, this, nullptr));
324 client_->set_protocol_config(protocol_config_->Clone()); 402 client_->set_protocol_config(protocol_config_->Clone());
325 client_->Start(client_signaling_.get(), std::move(client_authenticator), 403 client_->Start(client_signaling_.get(), std::move(client_authenticator),
326 transport_context, kHostJid, std::string()); 404 transport_context, kHostJid, std::string());
327 } 405 }
328 406
329 void FetchPin( 407 void FetchPin(
330 bool pairing_supported, 408 bool pairing_supported,
331 const protocol::SecretFetchedCallback& secret_fetched_callback) { 409 const protocol::SecretFetchedCallback& secret_fetched_callback) {
332 secret_fetched_callback.Run("123456"); 410 secret_fetched_callback.Run("123456");
333 } 411 }
334 412
413 void MeasureTotalLatency(bool webrtc) {
414 scoped_refptr<test::CyclicFrameGenerator> frame_generator =
415 test::CyclicFrameGenerator::Create();
416 frame_generator->set_draw_barcode(true);
417
418 desktop_environment_factory_.set_frame_generator(base::Bind(
419 &test::CyclicFrameGenerator::GenerateFrame, frame_generator));
420
421 StartHostAndClient(webrtc, protocol::ChannelConfig::CODEC_VP8);
422 ASSERT_NO_FATAL_FAILURE(WaitConnected());
423
424 base::TimeDelta total_latency_big_frames;
425 int big_frame_count = 0;
426 base::TimeDelta total_latency_small_frames;
427 int small_frame_count = 0;
428
429 int last_frame_id = -1;
430 for (int i = 0; i < 30; ++i) {
431 scoped_ptr<webrtc::DesktopFrame> frame = ReceiveFrame();
432 test::CyclicFrameGenerator::FrameInfo frame_info =
433 frame_generator->IdentifyFrame(frame.get());
434 base::TimeDelta latency = base::TimeTicks::Now() - frame_info.timestamp;
435
436 if (frame_info.frame_id > last_frame_id) {
437 last_frame_id = frame_info.frame_id;
438
439 switch (frame_info.type) {
440 case test::CyclicFrameGenerator::FrameType::EMPTY:
441 NOTREACHED();
442 break;
443 case test::CyclicFrameGenerator::FrameType::FULL:
444 total_latency_big_frames += latency;
445 ++big_frame_count;
446 break;
447 case test::CyclicFrameGenerator::FrameType::CURSOR:
448 total_latency_small_frames += latency;
449 ++small_frame_count;
450 break;
451 }
452 } else {
453 LOG(ERROR) << "Unexpected duplicate frame " << frame_info.frame_id;
454 }
455 }
456
457 CHECK(big_frame_count);
458 VLOG(0) << "Average latency for big frames: "
459 << (total_latency_big_frames / big_frame_count).InMillisecondsF();
460
461 if (small_frame_count) {
462 VLOG(0)
463 << "Average latency for small frames: "
464 << (total_latency_small_frames / small_frame_count).InMillisecondsF();
465 }
466 }
467
335 base::MessageLoopForIO message_loop_; 468 base::MessageLoopForIO message_loop_;
336 469
337 scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_; 470 scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_;
338 471
339 base::Thread host_thread_; 472 base::Thread host_thread_;
340 base::Thread capture_thread_; 473 base::Thread capture_thread_;
341 base::Thread encode_thread_; 474 base::Thread encode_thread_;
475 base::Thread decode_thread_;
342 FakeDesktopEnvironmentFactory desktop_environment_factory_; 476 FakeDesktopEnvironmentFactory desktop_environment_factory_;
343 477
344 FakeCursorShapeStub cursor_shape_stub_; 478 FakeCursorShapeStub cursor_shape_stub_;
345 479
346 scoped_ptr<protocol::CandidateSessionConfig> protocol_config_; 480 scoped_ptr<protocol::CandidateSessionConfig> protocol_config_;
347 481
348 scoped_ptr<FakeSignalStrategy> host_signaling_; 482 scoped_ptr<FakeSignalStrategy> host_signaling_;
349 scoped_ptr<FakeSignalStrategy> client_signaling_; 483 scoped_ptr<FakeSignalStrategy> client_signaling_;
350 484
351 scoped_ptr<ChromotingHost> host_; 485 scoped_ptr<ChromotingHost> host_;
352 scoped_ptr<ClientContext> client_context_; 486 scoped_ptr<ClientContext> client_context_;
353 scoped_ptr<ChromotingClient> client_; 487 scoped_ptr<ChromotingClient> client_;
488 webrtc::DesktopSize frame_size_;
489 scoped_ptr<VideoDecoder> video_decoder_;
354 490
355 scoped_ptr<base::RunLoop> connecting_loop_; 491 scoped_ptr<base::RunLoop> connecting_loop_;
356 scoped_ptr<base::RunLoop> waiting_frames_loop_; 492 scoped_ptr<base::RunLoop> waiting_frames_loop_;
357 493
358 bool client_connected_; 494 bool client_connected_;
359 bool host_connected_; 495 bool host_connected_;
360 496
361 base::Closure on_frame_task_; 497 base::Closure on_frame_task_;
362 498
363 scoped_ptr<VideoPacket> last_video_packet_; 499 scoped_ptr<VideoPacket> last_video_packet_;
500 scoped_ptr<webrtc::DesktopFrame> last_video_frame_;
364 501
365 private: 502 private:
366 DISALLOW_COPY_AND_ASSIGN(ProtocolPerfTest); 503 DISALLOW_COPY_AND_ASSIGN(ProtocolPerfTest);
367 }; 504 };
368 505
369 INSTANTIATE_TEST_CASE_P( 506 INSTANTIATE_TEST_CASE_P(
370 NoDelay, 507 NoDelay,
371 ProtocolPerfTest, 508 ProtocolPerfTest,
372 ::testing::Values(NetworkPerformanceParams(0, 0, 0, 0, 0.0))); 509 ::testing::Values(NetworkPerformanceParams(0, 0, 0, 0, 0.0)));
373 510
(...skipping 19 matching lines...) Expand all
393 // 100 MBps 530 // 100 MBps
394 NetworkPerformanceParams(800000000, 800000000, 2, 1, 0.0), 531 NetworkPerformanceParams(800000000, 800000000, 2, 1, 0.0),
395 // 8 MBps 532 // 8 MBps
396 NetworkPerformanceParams(1000000, 300000, 30, 5, 0.01), 533 NetworkPerformanceParams(1000000, 300000, 30, 5, 0.01),
397 NetworkPerformanceParams(1000000, 2000000, 30, 5, 0.01), 534 NetworkPerformanceParams(1000000, 2000000, 30, 5, 0.01),
398 // 800 kBps 535 // 800 kBps
399 NetworkPerformanceParams(100000, 30000, 130, 5, 0.01), 536 NetworkPerformanceParams(100000, 30000, 130, 5, 0.01),
400 NetworkPerformanceParams(100000, 200000, 130, 5, 0.01))); 537 NetworkPerformanceParams(100000, 200000, 130, 5, 0.01)));
401 538
402 TEST_P(ProtocolPerfTest, StreamFrameRate) { 539 TEST_P(ProtocolPerfTest, StreamFrameRate) {
403 StartHostAndClient(protocol::ChannelConfig::CODEC_VP8); 540 StartHostAndClient(false, protocol::ChannelConfig::CODEC_VP8);
404 ASSERT_NO_FATAL_FAILURE(WaitConnected()); 541 ASSERT_NO_FATAL_FAILURE(WaitConnected());
405 542
406 base::TimeDelta latency; 543 base::TimeDelta latency;
407 544
408 ReceiveFrame(&latency); 545 ReceiveFrameAndGetLatency(&latency);
409 LOG(INFO) << "First frame latency: " << latency.InMillisecondsF() << "ms"; 546 LOG(INFO) << "First frame latency: " << latency.InMillisecondsF() << "ms";
410 ReceiveFrames(20, nullptr); 547 ReceiveMultipleFramesAndGetMaxLatency(20, nullptr);
411 548
412 base::TimeTicks started = base::TimeTicks::Now(); 549 base::TimeTicks started = base::TimeTicks::Now();
413 ReceiveFrames(40, &latency); 550 ReceiveMultipleFramesAndGetMaxLatency(40, &latency);
414 base::TimeDelta elapsed = base::TimeTicks::Now() - started; 551 base::TimeDelta elapsed = base::TimeTicks::Now() - started;
415 LOG(INFO) << "Frame rate: " << (40.0 / elapsed.InSecondsF()); 552 LOG(INFO) << "Frame rate: " << (40.0 / elapsed.InSecondsF());
416 LOG(INFO) << "Maximum latency: " << latency.InMillisecondsF() << "ms"; 553 LOG(INFO) << "Maximum latency: " << latency.InMillisecondsF() << "ms";
417 } 554 }
418 555
419 const int kIntermittentFrameSize = 100 * 1000; 556 const int kIntermittentFrameSize = 100 * 1000;
420 557
421 // Frame generator that rewrites the whole screen every 60th frame. Should only 558 // Frame generator that rewrites the whole screen every 60th frame. Should only
422 // be used with the VERBATIM codec as the allocated frame may contain arbitrary 559 // be used with the VERBATIM codec as the allocated frame may contain arbitrary
423 // data. 560 // data.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 scoped_ptr<webrtc::SharedDesktopFrame> current_frame_; 594 scoped_ptr<webrtc::SharedDesktopFrame> current_frame_;
458 595
459 DISALLOW_COPY_AND_ASSIGN(IntermittentChangeFrameGenerator); 596 DISALLOW_COPY_AND_ASSIGN(IntermittentChangeFrameGenerator);
460 }; 597 };
461 598
462 TEST_P(ProtocolPerfTest, IntermittentChanges) { 599 TEST_P(ProtocolPerfTest, IntermittentChanges) {
463 desktop_environment_factory_.set_frame_generator( 600 desktop_environment_factory_.set_frame_generator(
464 base::Bind(&IntermittentChangeFrameGenerator::GenerateFrame, 601 base::Bind(&IntermittentChangeFrameGenerator::GenerateFrame,
465 new IntermittentChangeFrameGenerator())); 602 new IntermittentChangeFrameGenerator()));
466 603
467 StartHostAndClient(protocol::ChannelConfig::CODEC_VERBATIM); 604 StartHostAndClient(false, protocol::ChannelConfig::CODEC_VERBATIM);
468 ASSERT_NO_FATAL_FAILURE(WaitConnected()); 605 ASSERT_NO_FATAL_FAILURE(WaitConnected());
469 606
470 ReceiveFrame(nullptr); 607 ReceiveFrameAndGetLatency(nullptr);
471 608
472 base::TimeDelta expected = GetParam().latency_average; 609 base::TimeDelta expected = GetParam().latency_average;
473 if (GetParam().bandwidth > 0) { 610 if (GetParam().bandwidth > 0) {
474 expected += base::TimeDelta::FromSecondsD(kIntermittentFrameSize / 611 expected += base::TimeDelta::FromSecondsD(kIntermittentFrameSize /
475 GetParam().bandwidth); 612 GetParam().bandwidth);
476 } 613 }
477 LOG(INFO) << "Expected: " << expected.InMillisecondsF() << "ms"; 614 LOG(INFO) << "Expected: " << expected.InMillisecondsF() << "ms";
478 615
479 base::TimeDelta sum; 616 base::TimeDelta sum;
480 617
481 const int kFrames = 5; 618 const int kFrames = 5;
482 for (int i = 0; i < kFrames; ++i) { 619 for (int i = 0; i < kFrames; ++i) {
483 base::TimeDelta latency; 620 base::TimeDelta latency;
484 ReceiveFrame(&latency); 621 ReceiveFrameAndGetLatency(&latency);
485 LOG(INFO) << "Latency: " << latency.InMillisecondsF() 622 LOG(INFO) << "Latency: " << latency.InMillisecondsF()
486 << "ms Encode: " << last_video_packet_->encode_time_ms() 623 << "ms Encode: " << last_video_packet_->encode_time_ms()
487 << "ms Capture: " << last_video_packet_->capture_time_ms() 624 << "ms Capture: " << last_video_packet_->capture_time_ms()
488 << "ms"; 625 << "ms";
489 sum += latency; 626 sum += latency;
490 } 627 }
491 628
492 LOG(INFO) << "Average: " << (sum / kFrames).InMillisecondsF(); 629 LOG(INFO) << "Average: " << (sum / kFrames).InMillisecondsF();
493 } 630 }
494 631
632 TEST_P(ProtocolPerfTest, TotalLatencyIce) {
633 MeasureTotalLatency(false);
634 }
635
636 TEST_P(ProtocolPerfTest, TotalLatencyWebrtc) {
637 MeasureTotalLatency(true);
638 }
639
495 } // namespace remoting 640 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/test/fake_socket_factory.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698