| 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" | |
| 47 #include "testing/gtest/include/gtest/gtest.h" | 46 #include "testing/gtest/include/gtest/gtest.h" |
| 48 | 47 |
| 49 namespace remoting { | 48 namespace remoting { |
| 50 | 49 |
| 51 using protocol::ChannelConfig; | 50 using protocol::ChannelConfig; |
| 52 | 51 |
| 53 namespace { | 52 namespace { |
| 54 | 53 |
| 55 const char kHostJid[] = "host_jid@example.com/host"; | 54 const char kHostJid[] = "host_jid@example.com/host"; |
| 56 const char kHostOwner[] = "jane.doe@example.com"; | 55 const char kHostOwner[] = "jane.doe@example.com"; |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 client_->Start(client_signaling_.get(), client_auth_config, | 408 client_->Start(client_signaling_.get(), client_auth_config, |
| 410 transport_context, kHostJid, std::string()); | 409 transport_context, kHostJid, std::string()); |
| 411 } | 410 } |
| 412 | 411 |
| 413 void FetchPin( | 412 void FetchPin( |
| 414 bool pairing_supported, | 413 bool pairing_supported, |
| 415 const protocol::SecretFetchedCallback& secret_fetched_callback) { | 414 const protocol::SecretFetchedCallback& secret_fetched_callback) { |
| 416 secret_fetched_callback.Run(kHostPin); | 415 secret_fetched_callback.Run(kHostPin); |
| 417 } | 416 } |
| 418 | 417 |
| 419 void MeasureTotalLatency(bool use_webrtc); | 418 void MeasureTotalLatency(bool webrtc) { |
| 420 void MeasureScrollPerformance(bool use_webrtc); | 419 scoped_refptr<test::CyclicFrameGenerator> frame_generator = |
| 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 } |
| 421 | 475 |
| 422 base::MessageLoopForIO message_loop_; | 476 base::MessageLoopForIO message_loop_; |
| 423 | 477 |
| 424 scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_; | 478 scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_; |
| 425 | 479 |
| 426 base::Thread host_thread_; | 480 base::Thread host_thread_; |
| 427 base::Thread capture_thread_; | 481 base::Thread capture_thread_; |
| 428 base::Thread encode_thread_; | 482 base::Thread encode_thread_; |
| 429 base::Thread decode_thread_; | 483 base::Thread decode_thread_; |
| 430 FakeDesktopEnvironmentFactory desktop_environment_factory_; | 484 FakeDesktopEnvironmentFactory desktop_environment_factory_; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 ::testing::Values(NetworkPerformanceParams(0, 0, 2, 0, 0.01), | 528 ::testing::Values(NetworkPerformanceParams(0, 0, 2, 0, 0.01), |
| 475 NetworkPerformanceParams(0, 0, 30, 1, 0.01), | 529 NetworkPerformanceParams(0, 0, 30, 1, 0.01), |
| 476 NetworkPerformanceParams(0, 0, 30, 1, 0.1), | 530 NetworkPerformanceParams(0, 0, 30, 1, 0.1), |
| 477 NetworkPerformanceParams(0, 0, 300, 20, 0.01), | 531 NetworkPerformanceParams(0, 0, 300, 20, 0.01), |
| 478 NetworkPerformanceParams(0, 0, 300, 20, 0.1))); | 532 NetworkPerformanceParams(0, 0, 300, 20, 0.1))); |
| 479 | 533 |
| 480 INSTANTIATE_TEST_CASE_P( | 534 INSTANTIATE_TEST_CASE_P( |
| 481 LimitedBandwidth, | 535 LimitedBandwidth, |
| 482 ProtocolPerfTest, | 536 ProtocolPerfTest, |
| 483 ::testing::Values( | 537 ::testing::Values( |
| 484 // 100 Mbps | 538 // 100 MBps |
| 485 NetworkPerformanceParams(12500000, 12500000, 2, 1, 0.0), | 539 NetworkPerformanceParams(800000000, 800000000, 2, 1, 0.0), |
| 486 // 8 Mbps | 540 // 8 MBps |
| 487 NetworkPerformanceParams(1000000, 300000, 30, 5, 0.01), | 541 NetworkPerformanceParams(1000000, 300000, 30, 5, 0.01), |
| 488 NetworkPerformanceParams(1000000, 2000000, 30, 5, 0.01), | 542 NetworkPerformanceParams(1000000, 2000000, 30, 5, 0.01), |
| 489 // 800 kBps | 543 // 800 kBps |
| 490 NetworkPerformanceParams(100000, 30000, 130, 5, 0.01), | 544 NetworkPerformanceParams(100000, 30000, 130, 5, 0.01), |
| 491 NetworkPerformanceParams(100000, 200000, 130, 5, 0.01))); | 545 NetworkPerformanceParams(100000, 200000, 130, 5, 0.01))); |
| 492 | 546 |
| 493 TEST_P(ProtocolPerfTest, StreamFrameRate) { | 547 TEST_P(ProtocolPerfTest, StreamFrameRate) { |
| 494 StartHostAndClient(false, protocol::ChannelConfig::CODEC_VP8); | 548 StartHostAndClient(false, protocol::ChannelConfig::CODEC_VP8); |
| 495 ASSERT_NO_FATAL_FAILURE(WaitConnected()); | 549 ASSERT_NO_FATAL_FAILURE(WaitConnected()); |
| 496 | 550 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 LOG(INFO) << "Latency: " << latency.InMillisecondsF() | 630 LOG(INFO) << "Latency: " << latency.InMillisecondsF() |
| 577 << "ms Encode: " << last_video_packet_->encode_time_ms() | 631 << "ms Encode: " << last_video_packet_->encode_time_ms() |
| 578 << "ms Capture: " << last_video_packet_->capture_time_ms() | 632 << "ms Capture: " << last_video_packet_->capture_time_ms() |
| 579 << "ms"; | 633 << "ms"; |
| 580 sum += latency; | 634 sum += latency; |
| 581 } | 635 } |
| 582 | 636 |
| 583 LOG(INFO) << "Average: " << (sum / kFrames).InMillisecondsF(); | 637 LOG(INFO) << "Average: " << (sum / kFrames).InMillisecondsF(); |
| 584 } | 638 } |
| 585 | 639 |
| 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 | |
| 648 TEST_P(ProtocolPerfTest, TotalLatencyIce) { | 640 TEST_P(ProtocolPerfTest, TotalLatencyIce) { |
| 649 MeasureTotalLatency(false); | 641 MeasureTotalLatency(false); |
| 650 } | 642 } |
| 651 | 643 |
| 652 TEST_P(ProtocolPerfTest, TotalLatencyWebrtc) { | 644 TEST_P(ProtocolPerfTest, TotalLatencyWebrtc) { |
| 653 MeasureTotalLatency(true); | 645 MeasureTotalLatency(true); |
| 654 } | 646 } |
| 655 | 647 |
| 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 | |
| 701 } // namespace remoting | 648 } // namespace remoting |
| OLD | NEW |