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

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

Issue 427613005: Implement network performance simulation for remoting perf tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « remoting/test/leaky_bucket.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 "base/base64.h" 5 #include "base/base64.h"
6 #include "base/file_util.h" 6 #include "base/file_util.h"
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/rand_util.h"
8 #include "base/run_loop.h" 9 #include "base/run_loop.h"
9 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
10 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
11 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
12 #include "jingle/glue/thread_wrapper.h" 13 #include "jingle/glue/thread_wrapper.h"
13 #include "net/base/test_data_directory.h" 14 #include "net/base/test_data_directory.h"
14 #include "net/url_request/url_request_context_getter.h" 15 #include "net/url_request/url_request_context_getter.h"
15 #include "remoting/base/rsa_key_pair.h" 16 #include "remoting/base/rsa_key_pair.h"
16 #include "remoting/client/audio_player.h" 17 #include "remoting/client/audio_player.h"
17 #include "remoting/client/chromoting_client.h" 18 #include "remoting/client/chromoting_client.h"
18 #include "remoting/client/client_context.h" 19 #include "remoting/client/client_context.h"
19 #include "remoting/client/client_user_interface.h" 20 #include "remoting/client/client_user_interface.h"
20 #include "remoting/client/video_renderer.h" 21 #include "remoting/client/video_renderer.h"
21 #include "remoting/host/chromoting_host.h" 22 #include "remoting/host/chromoting_host.h"
22 #include "remoting/host/chromoting_host_context.h" 23 #include "remoting/host/chromoting_host_context.h"
23 #include "remoting/host/fake_desktop_environment.h" 24 #include "remoting/host/fake_desktop_environment.h"
24 #include "remoting/host/video_scheduler.h" 25 #include "remoting/host/video_scheduler.h"
25 #include "remoting/protocol/chromium_port_allocator.h"
26 #include "remoting/protocol/jingle_session_manager.h" 26 #include "remoting/protocol/jingle_session_manager.h"
27 #include "remoting/protocol/libjingle_transport_factory.h" 27 #include "remoting/protocol/libjingle_transport_factory.h"
28 #include "remoting/protocol/me2me_host_authenticator_factory.h" 28 #include "remoting/protocol/me2me_host_authenticator_factory.h"
29 #include "remoting/protocol/negotiating_client_authenticator.h" 29 #include "remoting/protocol/negotiating_client_authenticator.h"
30 #include "remoting/protocol/session_config.h" 30 #include "remoting/protocol/session_config.h"
31 #include "remoting/signaling/fake_signal_strategy.h" 31 #include "remoting/signaling/fake_signal_strategy.h"
32 #include "remoting/test/fake_network_dispatcher.h"
33 #include "remoting/test/fake_port_allocator.h"
34 #include "remoting/test/fake_socket_factory.h"
32 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
33 36
34 namespace remoting { 37 namespace remoting {
35 38
36 using protocol::ChannelConfig; 39 using protocol::ChannelConfig;
37 40
38 const char kHostJid[] = "host_jid@example.com/host"; 41 const char kHostJid[] = "host_jid@example.com/host";
39 const char kHostOwner[] = "jane.doe@example.com"; 42 const char kHostOwner[] = "jane.doe@example.com";
40 const char kClientJid[] = "jane.doe@example.com/client"; 43 const char kClientJid[] = "jane.doe@example.com/client";
41 44
42 class ProtocolPerfTest : public testing::Test, 45 struct NetworkPerformanceParams {
43 public ClientUserInterface, 46 NetworkPerformanceParams(int bandwidth,
44 public VideoRenderer, 47 int max_buffers,
45 public HostStatusObserver { 48 double latency_average_ms,
49 double latency_stddev_ms,
50 double out_of_order_rate)
51 : bandwidth(bandwidth),
52 max_buffers(max_buffers),
53 latency_average(base::TimeDelta::FromMillisecondsD(latency_average_ms)),
54 latency_stddev(base::TimeDelta::FromMillisecondsD(latency_stddev_ms)),
55 out_of_order_rate(out_of_order_rate) {}
56
57 int bandwidth;
58 int max_buffers;
59 base::TimeDelta latency_average;
60 base::TimeDelta latency_stddev;
61 double out_of_order_rate;
62 };
63
64 class ProtocolPerfTest
65 : public testing::Test,
66 public testing::WithParamInterface<NetworkPerformanceParams>,
67 public ClientUserInterface,
68 public VideoRenderer,
69 public HostStatusObserver {
46 public: 70 public:
47 ProtocolPerfTest() 71 ProtocolPerfTest()
48 : host_thread_("host"), 72 : host_thread_("host"),
49 capture_thread_("capture"), 73 capture_thread_("capture"),
50 encode_thread_("encode") { 74 encode_thread_("encode") {
51 VideoScheduler::EnableTimestampsForTests(); 75 VideoScheduler::EnableTimestampsForTests();
52 host_thread_.StartWithOptions( 76 host_thread_.StartWithOptions(
53 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 77 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
54 capture_thread_.Start(); 78 capture_thread_.Start();
55 encode_thread_.Start(); 79 encode_thread_.Start();
56 } 80 }
81
57 virtual ~ProtocolPerfTest() { 82 virtual ~ProtocolPerfTest() {
58 host_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, host_.release()); 83 host_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, host_.release());
59 host_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, 84 host_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE,
60 host_signaling_.release()); 85 host_signaling_.release());
61 message_loop_.RunUntilIdle(); 86 message_loop_.RunUntilIdle();
62 } 87 }
63 88
64 // ClientUserInterface interface. 89 // ClientUserInterface interface.
65 virtual void OnConnectionState(protocol::ConnectionToHost::State state, 90 virtual void OnConnectionState(protocol::ConnectionToHost::State state,
66 protocol::ErrorCode error) OVERRIDE { 91 protocol::ErrorCode error) OVERRIDE {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 *max_latency = latency; 180 *max_latency = latency;
156 } 181 }
157 } 182 }
158 } 183 }
159 184
160 // Creates test host and client and starts connection between them. Caller 185 // Creates test host and client and starts connection between them. Caller
161 // should call WaitConnected() to wait until connection is established. The 186 // should call WaitConnected() to wait until connection is established. The
162 // host is started on |host_thread_| while the client works on the main 187 // host is started on |host_thread_| while the client works on the main
163 // thread. 188 // thread.
164 void StartHostAndClient(protocol::ChannelConfig::Codec video_codec) { 189 void StartHostAndClient(protocol::ChannelConfig::Codec video_codec) {
190 fake_network_dispatcher_ = new FakeNetworkDispatcher();
191
165 client_signaling_.reset(new FakeSignalStrategy(kClientJid)); 192 client_signaling_.reset(new FakeSignalStrategy(kClientJid));
166 193
167 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); 194 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
168 195
169 protocol_config_ = protocol::CandidateSessionConfig::CreateDefault(); 196 protocol_config_ = protocol::CandidateSessionConfig::CreateDefault();
170 protocol_config_->DisableAudioChannel(); 197 protocol_config_->DisableAudioChannel();
171 protocol_config_->mutable_video_configs()->clear(); 198 protocol_config_->mutable_video_configs()->clear();
172 protocol_config_->mutable_video_configs()->push_back( 199 protocol_config_->mutable_video_configs()->push_back(
173 protocol::ChannelConfig( 200 protocol::ChannelConfig(
174 protocol::ChannelConfig::TRANSPORT_STREAM, 2, video_codec)); 201 protocol::ChannelConfig::TRANSPORT_STREAM, 2, video_codec));
175 202
176 host_thread_.message_loop_proxy()->PostTask( 203 host_thread_.message_loop_proxy()->PostTask(
177 FROM_HERE, 204 FROM_HERE,
178 base::Bind(&ProtocolPerfTest::StartHost, base::Unretained(this))); 205 base::Bind(&ProtocolPerfTest::StartHost, base::Unretained(this)));
179 } 206 }
180 207
181 void StartHost() { 208 void StartHost() {
182 DCHECK(host_thread_.message_loop_proxy()->BelongsToCurrentThread()); 209 DCHECK(host_thread_.message_loop_proxy()->BelongsToCurrentThread());
183 210
184 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); 211 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
185 212
186 host_signaling_.reset(new FakeSignalStrategy(kHostJid)); 213 host_signaling_.reset(new FakeSignalStrategy(kHostJid));
187 host_signaling_->ConnectTo(client_signaling_.get()); 214 host_signaling_->ConnectTo(client_signaling_.get());
188 215
189 protocol::NetworkSettings network_settings( 216 protocol::NetworkSettings network_settings(
190 protocol::NetworkSettings::NAT_TRAVERSAL_OUTGOING); 217 protocol::NetworkSettings::NAT_TRAVERSAL_OUTGOING);
191 218
192 // TODO(sergeyu): Replace with a fake port allocator. 219 scoped_ptr<FakePortAllocator> port_allocator(
193 scoped_ptr<cricket::HttpPortAllocatorBase> host_port_allocator = 220 FakePortAllocator::Create(fake_network_dispatcher_));
194 protocol::ChromiumPortAllocator::Create(NULL, network_settings) 221 port_allocator->socket_factory()->SetBandwidth(GetParam().bandwidth,
195 .PassAs<cricket::HttpPortAllocatorBase>(); 222 GetParam().max_buffers);
196 223 port_allocator->socket_factory()->SetLatency(GetParam().latency_average,
224 GetParam().latency_stddev);
225 port_allocator->socket_factory()->set_out_of_order_rate(
226 GetParam().out_of_order_rate);
197 scoped_ptr<protocol::TransportFactory> host_transport_factory( 227 scoped_ptr<protocol::TransportFactory> host_transport_factory(
198 new protocol::LibjingleTransportFactory( 228 new protocol::LibjingleTransportFactory(
199 host_signaling_.get(), 229 host_signaling_.get(),
200 host_port_allocator.Pass(), 230 port_allocator.PassAs<cricket::HttpPortAllocatorBase>(),
201 network_settings)); 231 network_settings));
202 232
203 scoped_ptr<protocol::SessionManager> session_manager( 233 scoped_ptr<protocol::SessionManager> session_manager(
204 new protocol::JingleSessionManager(host_transport_factory.Pass())); 234 new protocol::JingleSessionManager(host_transport_factory.Pass()));
205 235
206 // Encoder runs on a separate thread, main thread is used for everything 236 // Encoder runs on a separate thread, main thread is used for everything
207 // else. 237 // else.
208 host_.reset(new ChromotingHost(host_signaling_.get(), 238 host_.reset(new ChromotingHost(host_signaling_.get(),
209 &desktop_environment_factory_, 239 &desktop_environment_factory_,
210 session_manager.Pass(), 240 session_manager.Pass(),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 void StartClientAfterHost() { 280 void StartClientAfterHost() {
251 client_signaling_->ConnectTo(host_signaling_.get()); 281 client_signaling_->ConnectTo(host_signaling_.get());
252 282
253 protocol::NetworkSettings network_settings( 283 protocol::NetworkSettings network_settings(
254 protocol::NetworkSettings::NAT_TRAVERSAL_OUTGOING); 284 protocol::NetworkSettings::NAT_TRAVERSAL_OUTGOING);
255 285
256 // Initialize client. 286 // Initialize client.
257 client_context_.reset( 287 client_context_.reset(
258 new ClientContext(base::ThreadTaskRunnerHandle::Get())); 288 new ClientContext(base::ThreadTaskRunnerHandle::Get()));
259 289
260 // TODO(sergeyu): Replace with a fake port allocator 290 scoped_ptr<FakePortAllocator> port_allocator(
261 scoped_ptr<cricket::HttpPortAllocatorBase> client_port_allocator = 291 FakePortAllocator::Create(fake_network_dispatcher_));
262 protocol::ChromiumPortAllocator::Create(NULL, network_settings) 292 port_allocator->socket_factory()->SetBandwidth(GetParam().bandwidth,
263 .PassAs<cricket::HttpPortAllocatorBase>(); 293 GetParam().max_buffers);
264 294 port_allocator->socket_factory()->SetLatency(GetParam().latency_average,
295 GetParam().latency_stddev);
296 port_allocator->socket_factory()->set_out_of_order_rate(
297 GetParam().out_of_order_rate);
265 scoped_ptr<protocol::TransportFactory> client_transport_factory( 298 scoped_ptr<protocol::TransportFactory> client_transport_factory(
266 new protocol::LibjingleTransportFactory(client_signaling_.get(), 299 new protocol::LibjingleTransportFactory(
267 client_port_allocator.Pass(), 300 client_signaling_.get(),
268 network_settings)); 301 port_allocator.PassAs<cricket::HttpPortAllocatorBase>(),
302 network_settings));
269 303
270 std::vector<protocol::AuthenticationMethod> auth_methods; 304 std::vector<protocol::AuthenticationMethod> auth_methods;
271 auth_methods.push_back(protocol::AuthenticationMethod::Spake2( 305 auth_methods.push_back(protocol::AuthenticationMethod::Spake2(
272 protocol::AuthenticationMethod::NONE)); 306 protocol::AuthenticationMethod::NONE));
273 scoped_ptr<protocol::Authenticator> client_authenticator( 307 scoped_ptr<protocol::Authenticator> client_authenticator(
274 new protocol::NegotiatingClientAuthenticator( 308 new protocol::NegotiatingClientAuthenticator(
275 std::string(), // client_pairing_id 309 std::string(), // client_pairing_id
276 std::string(), // client_pairing_secret 310 std::string(), // client_pairing_secret
277 std::string(), // authentication_tag 311 std::string(), // authentication_tag
278 base::Bind(&ProtocolPerfTest::FetchPin, base::Unretained(this)), 312 base::Bind(&ProtocolPerfTest::FetchPin, base::Unretained(this)),
279 scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>(), 313 scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>(),
280 auth_methods)); 314 auth_methods));
281 client_.reset(new ChromotingClient( 315 client_.reset(new ChromotingClient(
282 client_context_.get(), this, this, scoped_ptr<AudioPlayer>())); 316 client_context_.get(), this, this, scoped_ptr<AudioPlayer>()));
283 client_->SetProtocolConfigForTests(protocol_config_->Clone()); 317 client_->SetProtocolConfigForTests(protocol_config_->Clone());
284 client_->Start( 318 client_->Start(
285 client_signaling_.get(), client_authenticator.Pass(), 319 client_signaling_.get(), client_authenticator.Pass(),
286 client_transport_factory.Pass(), kHostJid, std::string()); 320 client_transport_factory.Pass(), kHostJid, std::string());
287 } 321 }
288 322
289 void FetchPin( 323 void FetchPin(
290 bool pairing_supported, 324 bool pairing_supported,
291 const protocol::SecretFetchedCallback& secret_fetched_callback) { 325 const protocol::SecretFetchedCallback& secret_fetched_callback) {
292 secret_fetched_callback.Run("123456"); 326 secret_fetched_callback.Run("123456");
293 } 327 }
294 328
295 base::MessageLoopForIO message_loop_; 329 base::MessageLoopForIO message_loop_;
296 330
331 scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_;
332
297 base::Thread host_thread_; 333 base::Thread host_thread_;
298 base::Thread capture_thread_; 334 base::Thread capture_thread_;
299 base::Thread encode_thread_; 335 base::Thread encode_thread_;
300 FakeDesktopEnvironmentFactory desktop_environment_factory_; 336 FakeDesktopEnvironmentFactory desktop_environment_factory_;
301 337
302 scoped_ptr<protocol::CandidateSessionConfig> protocol_config_; 338 scoped_ptr<protocol::CandidateSessionConfig> protocol_config_;
303 339
304 scoped_ptr<FakeSignalStrategy> host_signaling_; 340 scoped_ptr<FakeSignalStrategy> host_signaling_;
305 scoped_ptr<FakeSignalStrategy> client_signaling_; 341 scoped_ptr<FakeSignalStrategy> client_signaling_;
306 342
307 scoped_ptr<ChromotingHost> host_; 343 scoped_ptr<ChromotingHost> host_;
308 scoped_ptr<ClientContext> client_context_; 344 scoped_ptr<ClientContext> client_context_;
309 scoped_ptr<ChromotingClient> client_; 345 scoped_ptr<ChromotingClient> client_;
310 346
311 scoped_ptr<base::RunLoop> connecting_loop_; 347 scoped_ptr<base::RunLoop> connecting_loop_;
312 scoped_ptr<base::RunLoop> waiting_frames_loop_; 348 scoped_ptr<base::RunLoop> waiting_frames_loop_;
313 349
314 bool client_connected_; 350 bool client_connected_;
315 bool host_connected_; 351 bool host_connected_;
316 352
317 base::Closure on_frame_task_; 353 base::Closure on_frame_task_;
318 354
319 scoped_ptr<VideoPacket> last_video_packet_; 355 scoped_ptr<VideoPacket> last_video_packet_;
320 356
321 DISALLOW_COPY_AND_ASSIGN(ProtocolPerfTest); 357 DISALLOW_COPY_AND_ASSIGN(ProtocolPerfTest);
322 }; 358 };
323 359
324 TEST_F(ProtocolPerfTest, StreamFrameRate) { 360 INSTANTIATE_TEST_CASE_P(
361 NoDelay,
362 ProtocolPerfTest,
363 ::testing::Values(NetworkPerformanceParams(0, 0, 0, 0, 0.0)));
364
365 INSTANTIATE_TEST_CASE_P(
366 HighLatency,
367 ProtocolPerfTest,
368 ::testing::Values(NetworkPerformanceParams(0, 0, 300, 30, 0.0),
369 NetworkPerformanceParams(0, 0, 30, 10, 0.0)));
370
371 INSTANTIATE_TEST_CASE_P(
372 OutOfOrder,
373 ProtocolPerfTest,
374 ::testing::Values(NetworkPerformanceParams(0, 0, 2, 0, 0.01),
375 NetworkPerformanceParams(0, 0, 30, 1, 0.01),
376 NetworkPerformanceParams(0, 0, 30, 1, 0.1),
377 NetworkPerformanceParams(0, 0, 300, 20, 0.01),
378 NetworkPerformanceParams(0, 0, 300, 20, 0.1)));
379
380 INSTANTIATE_TEST_CASE_P(
381 LimitedBandwidth,
382 ProtocolPerfTest,
383 ::testing::Values(
384 // 100 MBps
385 NetworkPerformanceParams(800000000, 800000000, 2, 1, 0.0),
386 // 8 MBps
387 NetworkPerformanceParams(1000000, 300000, 30, 5, 0.01),
388 NetworkPerformanceParams(1000000, 2000000, 30, 5, 0.01),
389 // 800 kBps
390 NetworkPerformanceParams(100000, 30000, 130, 5, 0.01),
391 NetworkPerformanceParams(100000, 200000, 130, 5, 0.01)));
392
393 TEST_P(ProtocolPerfTest, StreamFrameRate) {
325 StartHostAndClient(protocol::ChannelConfig::CODEC_VP8); 394 StartHostAndClient(protocol::ChannelConfig::CODEC_VP8);
326 ASSERT_NO_FATAL_FAILURE(WaitConnected()); 395 ASSERT_NO_FATAL_FAILURE(WaitConnected());
327 396
328 base::TimeDelta latency; 397 base::TimeDelta latency;
329 398
330 ReceiveFrame(&latency); 399 ReceiveFrame(&latency);
331 LOG(INFO) << "First frame latency: " << latency.InMillisecondsF() << "ms"; 400 LOG(INFO) << "First frame latency: " << latency.InMillisecondsF() << "ms";
332 ReceiveFrames(20, NULL); 401 ReceiveFrames(20, NULL);
333 402
334 base::TimeTicks started = base::TimeTicks::Now(); 403 base::TimeTicks started = base::TimeTicks::Now();
335 ReceiveFrames(40, &latency); 404 ReceiveFrames(40, &latency);
336 base::TimeDelta elapsed = base::TimeTicks::Now() - started; 405 base::TimeDelta elapsed = base::TimeTicks::Now() - started;
337 LOG(INFO) << "Frame rate: " << (40.0 / elapsed.InSecondsF()); 406 LOG(INFO) << "Frame rate: " << (40.0 / elapsed.InSecondsF());
338 LOG(INFO) << "Maximum latency: " << latency.InMillisecondsF() << "ms"; 407 LOG(INFO) << "Maximum latency: " << latency.InMillisecondsF() << "ms";
339 } 408 }
340 409
410 const int kIntermittentFrameSize = 100 * 1000;
411
341 // Frame generator that rewrites the whole screen every 60th frame. Should only 412 // Frame generator that rewrites the whole screen every 60th frame. Should only
342 // be used with the VERBATIM codec as the allocated frame may contain arbitrary 413 // be used with the VERBATIM codec as the allocated frame may contain arbitrary
343 // data. 414 // data.
344 class IntermittentChangeFrameGenerator 415 class IntermittentChangeFrameGenerator
345 : public base::RefCountedThreadSafe<IntermittentChangeFrameGenerator> { 416 : public base::RefCountedThreadSafe<IntermittentChangeFrameGenerator> {
346 public: 417 public:
347 IntermittentChangeFrameGenerator() 418 IntermittentChangeFrameGenerator()
348 : frame_index_(0) {} 419 : frame_index_(0) {}
349 420
350 scoped_ptr<webrtc::DesktopFrame> GenerateFrame( 421 scoped_ptr<webrtc::DesktopFrame> GenerateFrame(
351 webrtc::DesktopCapturer::Callback* callback) { 422 webrtc::DesktopCapturer::Callback* callback) {
352 const int kWidth = 800; 423 const int kWidth = 1000;
353 const int kHeight = 600; 424 const int kHeight = kIntermittentFrameSize / kWidth / 4;
354 425
355 bool fresh_frame = false; 426 bool fresh_frame = false;
356 if (frame_index_ % 60 == 0 || !current_frame_) { 427 if (frame_index_ % 60 == 0 || !current_frame_) {
357 current_frame_.reset(webrtc::SharedDesktopFrame::Wrap( 428 current_frame_.reset(webrtc::SharedDesktopFrame::Wrap(
358 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight)))); 429 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight))));
359 fresh_frame = true; 430 fresh_frame = true;
360 } 431 }
361 ++frame_index_; 432 ++frame_index_;
362 433
363 scoped_ptr<webrtc::DesktopFrame> result(current_frame_->Share()); 434 scoped_ptr<webrtc::DesktopFrame> result(current_frame_->Share());
364 result->mutable_updated_region()->Clear(); 435 result->mutable_updated_region()->Clear();
365 if (fresh_frame) { 436 if (fresh_frame) {
366 result->mutable_updated_region()->AddRect( 437 result->mutable_updated_region()->AddRect(
367 webrtc::DesktopRect::MakeXYWH(0, 0, kWidth, kHeight)); 438 webrtc::DesktopRect::MakeXYWH(0, 0, kWidth, kHeight));
368 } 439 }
369 return result.Pass(); 440 return result.Pass();
370 } 441 }
371 442
372 private: 443 private:
373 ~IntermittentChangeFrameGenerator() {} 444 ~IntermittentChangeFrameGenerator() {}
374 friend class base::RefCountedThreadSafe<IntermittentChangeFrameGenerator>; 445 friend class base::RefCountedThreadSafe<IntermittentChangeFrameGenerator>;
375 446
376 int frame_index_; 447 int frame_index_;
377 scoped_ptr<webrtc::SharedDesktopFrame> current_frame_; 448 scoped_ptr<webrtc::SharedDesktopFrame> current_frame_;
378 449
379 DISALLOW_COPY_AND_ASSIGN(IntermittentChangeFrameGenerator); 450 DISALLOW_COPY_AND_ASSIGN(IntermittentChangeFrameGenerator);
380 }; 451 };
381 452
382 TEST_F(ProtocolPerfTest, IntermittentChanges) { 453 TEST_P(ProtocolPerfTest, IntermittentChanges) {
383 desktop_environment_factory_.set_frame_generator( 454 desktop_environment_factory_.set_frame_generator(
384 base::Bind(&IntermittentChangeFrameGenerator::GenerateFrame, 455 base::Bind(&IntermittentChangeFrameGenerator::GenerateFrame,
385 new IntermittentChangeFrameGenerator())); 456 new IntermittentChangeFrameGenerator()));
386 457
387 StartHostAndClient(protocol::ChannelConfig::CODEC_VERBATIM); 458 StartHostAndClient(protocol::ChannelConfig::CODEC_VERBATIM);
388 ASSERT_NO_FATAL_FAILURE(WaitConnected()); 459 ASSERT_NO_FATAL_FAILURE(WaitConnected());
389 460
390 ReceiveFrame(NULL); 461 ReceiveFrame(NULL);
391 462
392 for (int i = 0; i < 5; ++i) { 463 base::TimeDelta expected = GetParam().latency_average;
464 if (GetParam().bandwidth > 0) {
465 expected += base::TimeDelta::FromSecondsD(kIntermittentFrameSize /
466 GetParam().bandwidth);
467 }
468 LOG(INFO) << "Expected: " << expected.InMillisecondsF() << "ms";
469
470 base::TimeDelta sum;
471
472 const int kFrames = 5;
473 for (int i = 0; i < kFrames; ++i) {
393 base::TimeDelta latency; 474 base::TimeDelta latency;
394 ReceiveFrame(&latency); 475 ReceiveFrame(&latency);
395 LOG(INFO) << "Latency: " << latency.InMillisecondsF() 476 LOG(INFO) << "Latency: " << latency.InMillisecondsF()
396 << "ms Encode: " << last_video_packet_->encode_time_ms() 477 << "ms Encode: " << last_video_packet_->encode_time_ms()
397 << "ms Capture: " << last_video_packet_->capture_time_ms() 478 << "ms Capture: " << last_video_packet_->capture_time_ms()
398 << "ms"; 479 << "ms";
480 sum += latency;
399 } 481 }
482
483 LOG(INFO) << "Average: " << (sum / kFrames).InMillisecondsF();
400 } 484 }
401 485
402 } // namespace remoting 486 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/test/leaky_bucket.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698