OLD | NEW |
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/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "remoting/protocol/me2me_host_authenticator_factory.h" | 36 #include "remoting/protocol/me2me_host_authenticator_factory.h" |
37 #include "remoting/protocol/session_config.h" | 37 #include "remoting/protocol/session_config.h" |
38 #include "remoting/protocol/transport_context.h" | 38 #include "remoting/protocol/transport_context.h" |
39 #include "remoting/protocol/video_frame_pump.h" | 39 #include "remoting/protocol/video_frame_pump.h" |
40 #include "remoting/protocol/video_renderer.h" | 40 #include "remoting/protocol/video_renderer.h" |
41 #include "remoting/signaling/fake_signal_strategy.h" | 41 #include "remoting/signaling/fake_signal_strategy.h" |
42 #include "remoting/test/cyclic_frame_generator.h" | 42 #include "remoting/test/cyclic_frame_generator.h" |
43 #include "remoting/test/fake_network_dispatcher.h" | 43 #include "remoting/test/fake_network_dispatcher.h" |
44 #include "remoting/test/fake_port_allocator.h" | 44 #include "remoting/test/fake_port_allocator.h" |
45 #include "remoting/test/fake_socket_factory.h" | 45 #include "remoting/test/fake_socket_factory.h" |
| 46 #include "remoting/test/scroll_frame_generator.h" |
46 #include "testing/gtest/include/gtest/gtest.h" | 47 #include "testing/gtest/include/gtest/gtest.h" |
47 | 48 |
48 namespace remoting { | 49 namespace remoting { |
49 | 50 |
50 using protocol::ChannelConfig; | 51 using protocol::ChannelConfig; |
51 | 52 |
52 namespace { | 53 namespace { |
53 | 54 |
54 const char kHostJid[] = "host_jid@example.com/host"; | 55 const char kHostJid[] = "host_jid@example.com/host"; |
55 const char kHostOwner[] = "jane.doe@example.com"; | 56 const char kHostOwner[] = "jane.doe@example.com"; |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 client_->Start(client_signaling_.get(), client_auth_config, | 409 client_->Start(client_signaling_.get(), client_auth_config, |
409 transport_context, kHostJid, std::string()); | 410 transport_context, kHostJid, std::string()); |
410 } | 411 } |
411 | 412 |
412 void FetchPin( | 413 void FetchPin( |
413 bool pairing_supported, | 414 bool pairing_supported, |
414 const protocol::SecretFetchedCallback& secret_fetched_callback) { | 415 const protocol::SecretFetchedCallback& secret_fetched_callback) { |
415 secret_fetched_callback.Run(kHostPin); | 416 secret_fetched_callback.Run(kHostPin); |
416 } | 417 } |
417 | 418 |
418 void MeasureTotalLatency(bool webrtc) { | 419 void MeasureTotalLatency(bool use_webrtc); |
419 scoped_refptr<test::CyclicFrameGenerator> frame_generator = | 420 void MeasureScrollPerformance(bool use_webrtc); |
420 test::CyclicFrameGenerator::Create(); | |
421 frame_generator->set_draw_barcode(true); | |
422 | |
423 desktop_environment_factory_.set_frame_generator(base::Bind( | |
424 &test::CyclicFrameGenerator::GenerateFrame, frame_generator)); | |
425 | |
426 StartHostAndClient(webrtc, protocol::ChannelConfig::CODEC_VP8); | |
427 ASSERT_NO_FATAL_FAILURE(WaitConnected()); | |
428 | |
429 int skipped_frames = 0; | |
430 while (skipped_frames < 10) { | |
431 std::unique_ptr<webrtc::DesktopFrame> frame = ReceiveFrame(); | |
432 test::CyclicFrameGenerator::ChangeInfoList changes = | |
433 frame_generator->GetChangeList(frame.get()); | |
434 skipped_frames += changes.size(); | |
435 } | |
436 | |
437 base::TimeDelta total_latency_big_frames; | |
438 int big_frame_count = 0; | |
439 base::TimeDelta total_latency_small_frames; | |
440 int small_frame_count = 0; | |
441 | |
442 while (big_frame_count + small_frame_count < 30) { | |
443 std::unique_ptr<webrtc::DesktopFrame> frame = ReceiveFrame(); | |
444 base::TimeTicks frame_received_time = base::TimeTicks::Now(); | |
445 test::CyclicFrameGenerator::ChangeInfoList changes = | |
446 frame_generator->GetChangeList(frame.get()); | |
447 for (auto& change_info : changes) { | |
448 base::TimeDelta latency = frame_received_time - change_info.timestamp; | |
449 switch (change_info.type) { | |
450 case test::CyclicFrameGenerator::ChangeType::NO_CHANGES: | |
451 NOTREACHED(); | |
452 break; | |
453 case test::CyclicFrameGenerator::ChangeType::FULL: | |
454 total_latency_big_frames += latency; | |
455 ++big_frame_count; | |
456 break; | |
457 case test::CyclicFrameGenerator::ChangeType::CURSOR: | |
458 total_latency_small_frames += latency; | |
459 ++small_frame_count; | |
460 break; | |
461 } | |
462 } | |
463 } | |
464 | |
465 CHECK(big_frame_count); | |
466 VLOG(0) << "Average latency for big frames: " | |
467 << (total_latency_big_frames / big_frame_count).InMillisecondsF(); | |
468 | |
469 if (small_frame_count) { | |
470 VLOG(0) | |
471 << "Average latency for small frames: " | |
472 << (total_latency_small_frames / small_frame_count).InMillisecondsF(); | |
473 } | |
474 } | |
475 | 421 |
476 base::MessageLoopForIO message_loop_; | 422 base::MessageLoopForIO message_loop_; |
477 | 423 |
478 scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_; | 424 scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_; |
479 | 425 |
480 base::Thread host_thread_; | 426 base::Thread host_thread_; |
481 base::Thread capture_thread_; | 427 base::Thread capture_thread_; |
482 base::Thread encode_thread_; | 428 base::Thread encode_thread_; |
483 base::Thread decode_thread_; | 429 base::Thread decode_thread_; |
484 FakeDesktopEnvironmentFactory desktop_environment_factory_; | 430 FakeDesktopEnvironmentFactory desktop_environment_factory_; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 ::testing::Values(NetworkPerformanceParams(0, 0, 2, 0, 0.01), | 474 ::testing::Values(NetworkPerformanceParams(0, 0, 2, 0, 0.01), |
529 NetworkPerformanceParams(0, 0, 30, 1, 0.01), | 475 NetworkPerformanceParams(0, 0, 30, 1, 0.01), |
530 NetworkPerformanceParams(0, 0, 30, 1, 0.1), | 476 NetworkPerformanceParams(0, 0, 30, 1, 0.1), |
531 NetworkPerformanceParams(0, 0, 300, 20, 0.01), | 477 NetworkPerformanceParams(0, 0, 300, 20, 0.01), |
532 NetworkPerformanceParams(0, 0, 300, 20, 0.1))); | 478 NetworkPerformanceParams(0, 0, 300, 20, 0.1))); |
533 | 479 |
534 INSTANTIATE_TEST_CASE_P( | 480 INSTANTIATE_TEST_CASE_P( |
535 LimitedBandwidth, | 481 LimitedBandwidth, |
536 ProtocolPerfTest, | 482 ProtocolPerfTest, |
537 ::testing::Values( | 483 ::testing::Values( |
538 // 100 MBps | 484 // 100 Mbps |
539 NetworkPerformanceParams(800000000, 800000000, 2, 1, 0.0), | 485 NetworkPerformanceParams(12500000, 12500000, 2, 1, 0.0), |
540 // 8 MBps | 486 // 8 Mbps |
541 NetworkPerformanceParams(1000000, 300000, 30, 5, 0.01), | 487 NetworkPerformanceParams(1000000, 300000, 30, 5, 0.01), |
542 NetworkPerformanceParams(1000000, 2000000, 30, 5, 0.01), | 488 NetworkPerformanceParams(1000000, 2000000, 30, 5, 0.01), |
543 // 800 kBps | 489 // 800 kBps |
544 NetworkPerformanceParams(100000, 30000, 130, 5, 0.01), | 490 NetworkPerformanceParams(100000, 30000, 130, 5, 0.01), |
545 NetworkPerformanceParams(100000, 200000, 130, 5, 0.01))); | 491 NetworkPerformanceParams(100000, 200000, 130, 5, 0.01))); |
546 | 492 |
547 TEST_P(ProtocolPerfTest, StreamFrameRate) { | 493 TEST_P(ProtocolPerfTest, StreamFrameRate) { |
548 StartHostAndClient(false, protocol::ChannelConfig::CODEC_VP8); | 494 StartHostAndClient(false, protocol::ChannelConfig::CODEC_VP8); |
549 ASSERT_NO_FATAL_FAILURE(WaitConnected()); | 495 ASSERT_NO_FATAL_FAILURE(WaitConnected()); |
550 | 496 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 LOG(INFO) << "Latency: " << latency.InMillisecondsF() | 576 LOG(INFO) << "Latency: " << latency.InMillisecondsF() |
631 << "ms Encode: " << last_video_packet_->encode_time_ms() | 577 << "ms Encode: " << last_video_packet_->encode_time_ms() |
632 << "ms Capture: " << last_video_packet_->capture_time_ms() | 578 << "ms Capture: " << last_video_packet_->capture_time_ms() |
633 << "ms"; | 579 << "ms"; |
634 sum += latency; | 580 sum += latency; |
635 } | 581 } |
636 | 582 |
637 LOG(INFO) << "Average: " << (sum / kFrames).InMillisecondsF(); | 583 LOG(INFO) << "Average: " << (sum / kFrames).InMillisecondsF(); |
638 } | 584 } |
639 | 585 |
| 586 // TotalLatency[Ice|Webrtc] tests measure video latency in the case when the |
| 587 // whole screen is updated occasionally. It's intended to simulate the case when |
| 588 // user actions (e.g. Alt-Tab, click on the task bar) cause whole screen to be |
| 589 // updated. |
| 590 void ProtocolPerfTest::MeasureTotalLatency(bool use_webrtc) { |
| 591 scoped_refptr<test::CyclicFrameGenerator> frame_generator = |
| 592 test::CyclicFrameGenerator::Create(); |
| 593 frame_generator->set_draw_barcode(true); |
| 594 |
| 595 desktop_environment_factory_.set_frame_generator( |
| 596 base::Bind(&test::CyclicFrameGenerator::GenerateFrame, frame_generator)); |
| 597 |
| 598 StartHostAndClient(use_webrtc, protocol::ChannelConfig::CODEC_VP8); |
| 599 ASSERT_NO_FATAL_FAILURE(WaitConnected()); |
| 600 |
| 601 int skipped_frames = 0; |
| 602 while (skipped_frames < 10) { |
| 603 std::unique_ptr<webrtc::DesktopFrame> frame = ReceiveFrame(); |
| 604 test::CyclicFrameGenerator::ChangeInfoList changes = |
| 605 frame_generator->GetChangeList(frame.get()); |
| 606 skipped_frames += changes.size(); |
| 607 } |
| 608 |
| 609 base::TimeDelta total_latency_big_frames; |
| 610 int big_frame_count = 0; |
| 611 base::TimeDelta total_latency_small_frames; |
| 612 int small_frame_count = 0; |
| 613 |
| 614 while (big_frame_count + small_frame_count < 30) { |
| 615 std::unique_ptr<webrtc::DesktopFrame> frame = ReceiveFrame(); |
| 616 base::TimeTicks frame_received_time = base::TimeTicks::Now(); |
| 617 test::CyclicFrameGenerator::ChangeInfoList changes = |
| 618 frame_generator->GetChangeList(frame.get()); |
| 619 for (auto& change_info : changes) { |
| 620 base::TimeDelta latency = frame_received_time - change_info.timestamp; |
| 621 switch (change_info.type) { |
| 622 case test::CyclicFrameGenerator::ChangeType::NO_CHANGES: |
| 623 NOTREACHED(); |
| 624 break; |
| 625 case test::CyclicFrameGenerator::ChangeType::FULL: |
| 626 total_latency_big_frames += latency; |
| 627 ++big_frame_count; |
| 628 break; |
| 629 case test::CyclicFrameGenerator::ChangeType::CURSOR: |
| 630 total_latency_small_frames += latency; |
| 631 ++small_frame_count; |
| 632 break; |
| 633 } |
| 634 } |
| 635 } |
| 636 |
| 637 CHECK(big_frame_count); |
| 638 VLOG(0) << "Average latency for big frames: " |
| 639 << (total_latency_big_frames / big_frame_count).InMillisecondsF(); |
| 640 |
| 641 if (small_frame_count) { |
| 642 VLOG(0) |
| 643 << "Average latency for small frames: " |
| 644 << (total_latency_small_frames / small_frame_count).InMillisecondsF(); |
| 645 } |
| 646 } |
| 647 |
640 TEST_P(ProtocolPerfTest, TotalLatencyIce) { | 648 TEST_P(ProtocolPerfTest, TotalLatencyIce) { |
641 MeasureTotalLatency(false); | 649 MeasureTotalLatency(false); |
642 } | 650 } |
643 | 651 |
644 TEST_P(ProtocolPerfTest, TotalLatencyWebrtc) { | 652 TEST_P(ProtocolPerfTest, TotalLatencyWebrtc) { |
645 MeasureTotalLatency(true); | 653 MeasureTotalLatency(true); |
646 } | 654 } |
647 | 655 |
| 656 // ScrollPerformance[Ice|Webrtc] tests simulate whole screen being scrolled |
| 657 // continuously. They measure FPS and video latency. |
| 658 void ProtocolPerfTest::MeasureScrollPerformance(bool use_webrtc) { |
| 659 scoped_refptr<test::ScrollFrameGenerator> frame_generator = |
| 660 new test::ScrollFrameGenerator(); |
| 661 |
| 662 desktop_environment_factory_.set_frame_generator( |
| 663 base::Bind(&test::ScrollFrameGenerator::GenerateFrame, frame_generator)); |
| 664 |
| 665 StartHostAndClient(use_webrtc, protocol::ChannelConfig::CODEC_VP8); |
| 666 ASSERT_NO_FATAL_FAILURE(WaitConnected()); |
| 667 |
| 668 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 669 const base::TimeDelta kWarmUpTime = base::TimeDelta::FromSeconds(2); |
| 670 while ((base::TimeTicks::Now() - start_time) < kWarmUpTime) { |
| 671 ReceiveFrame(); |
| 672 } |
| 673 |
| 674 // Run the test for 2 seconds. |
| 675 const base::TimeDelta kTestTime = base::TimeDelta::FromSeconds(2); |
| 676 |
| 677 int num_frames = 0; |
| 678 base::TimeDelta total_latency; |
| 679 start_time = base::TimeTicks::Now(); |
| 680 while ((base::TimeTicks::Now() - start_time) < kTestTime) { |
| 681 std::unique_ptr<webrtc::DesktopFrame> frame = ReceiveFrame(); |
| 682 ++num_frames; |
| 683 total_latency += frame_generator->GetFrameLatency(*frame); |
| 684 } |
| 685 |
| 686 VLOG(0) << "FPS: " |
| 687 << num_frames / (base::TimeTicks::Now() - start_time).InSecondsF(); |
| 688 |
| 689 VLOG(0) << "Average latency: " |
| 690 << (total_latency).InMillisecondsF() / num_frames; |
| 691 } |
| 692 |
| 693 TEST_P(ProtocolPerfTest, ScrollPerformanceIce) { |
| 694 MeasureScrollPerformance(false); |
| 695 } |
| 696 |
| 697 TEST_P(ProtocolPerfTest, ScrollPerformanceWebrtc) { |
| 698 MeasureScrollPerformance(true); |
| 699 } |
| 700 |
648 } // namespace remoting | 701 } // namespace remoting |
OLD | NEW |