| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <limits> | 11 #include <limits> |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "webrtc/base/logging.h" | 14 #include "webrtc/base/logging.h" |
| 15 #include "webrtc/system_wrappers/include/metrics_default.h" | 15 #include "webrtc/system_wrappers/include/metrics_default.h" |
| 16 #include "webrtc/test/encoder_settings.h" | 16 #include "webrtc/test/encoder_settings.h" |
| 17 #include "webrtc/test/fake_encoder.h" | 17 #include "webrtc/test/fake_encoder.h" |
| 18 #include "webrtc/test/frame_generator.h" | 18 #include "webrtc/test/frame_generator.h" |
| 19 #include "webrtc/test/gtest.h" | 19 #include "webrtc/test/gtest.h" |
| 20 #include "webrtc/video/send_statistics_proxy.h" | 20 #include "webrtc/video/send_statistics_proxy.h" |
| 21 #include "webrtc/video/vie_encoder.h" | 21 #include "webrtc/video/vie_encoder.h" |
| 22 | 22 |
| 23 namespace webrtc { | 23 namespace webrtc { |
| 24 | 24 |
| 25 using DegredationPreference = VideoSendStream::DegradationPreference; |
| 26 using ScaleReason = ScalingObserverInterface::ScaleReason; |
| 27 |
| 25 namespace { | 28 namespace { |
| 26 const size_t kMaxPayloadLength = 1440; | 29 const size_t kMaxPayloadLength = 1440; |
| 27 const int kTargetBitrateBps = 100000; | 30 const int kTargetBitrateBps = 100000; |
| 28 | 31 |
| 29 class TestBuffer : public webrtc::I420Buffer { | 32 class TestBuffer : public webrtc::I420Buffer { |
| 30 public: | 33 public: |
| 31 TestBuffer(rtc::Event* event, int width, int height) | 34 TestBuffer(rtc::Event* event, int width, int height) |
| 32 : I420Buffer(width, height), event_(event) {} | 35 : I420Buffer(width, height), event_(event) {} |
| 33 | 36 |
| 34 private: | 37 private: |
| 35 friend class rtc::RefCountedObject<TestBuffer>; | 38 friend class rtc::RefCountedObject<TestBuffer>; |
| 36 ~TestBuffer() override { | 39 ~TestBuffer() override { |
| 37 if (event_) | 40 if (event_) |
| 38 event_->Set(); | 41 event_->Set(); |
| 39 } | 42 } |
| 40 rtc::Event* const event_; | 43 rtc::Event* const event_; |
| 41 }; | 44 }; |
| 42 | 45 |
| 43 class ViEEncoderUnderTest : public ViEEncoder { | 46 class ViEEncoderUnderTest : public ViEEncoder { |
| 44 public: | 47 public: |
| 45 ViEEncoderUnderTest( | 48 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy, |
| 46 SendStatisticsProxy* stats_proxy, | 49 const VideoSendStream::Config::EncoderSettings& settings) |
| 47 const webrtc::VideoSendStream::Config::EncoderSettings& settings) | |
| 48 : ViEEncoder(1 /* number_of_cores */, | 50 : ViEEncoder(1 /* number_of_cores */, |
| 49 stats_proxy, | 51 stats_proxy, |
| 50 settings, | 52 settings, |
| 51 nullptr /* pre_encode_callback */, | 53 nullptr /* pre_encode_callback */, |
| 52 nullptr /* encoder_timing */) {} | 54 nullptr /* encoder_timing */) {} |
| 53 | 55 |
| 54 void TriggerCpuOveruse() { | 56 void PostTaskAndWait(bool down, ScaleReason reason) { |
| 55 rtc::Event event(false, false); | 57 rtc::Event event(false, false); |
| 56 encoder_queue()->PostTask([this, &event] { | 58 encoder_queue()->PostTask([this, &event, reason, down] { |
| 57 OveruseDetected(); | 59 down ? ScaleDown(reason) : ScaleUp(reason); |
| 58 event.Set(); | 60 event.Set(); |
| 59 }); | 61 }); |
| 60 event.Wait(rtc::Event::kForever); | 62 RTC_DCHECK(event.Wait(5000)); |
| 61 } | 63 } |
| 62 | 64 |
| 63 void TriggerCpuNormalUsage() { | 65 void TriggerCpuOveruse() { PostTaskAndWait(true, ScaleReason::kCpu); } |
| 64 rtc::Event event(false, false); | 66 |
| 65 encoder_queue()->PostTask([this, &event] { | 67 void TriggerCpuNormalUsage() { PostTaskAndWait(false, ScaleReason::kCpu); } |
| 66 NormalUsage(); | 68 |
| 67 event.Set(); | 69 void TriggerQualityLow() { PostTaskAndWait(true, ScaleReason::kQuality); } |
| 68 }); | 70 |
| 69 event.Wait(rtc::Event::kForever); | 71 void TriggerQualityHigh() { PostTaskAndWait(false, ScaleReason::kQuality); } |
| 70 } | |
| 71 }; | 72 }; |
| 72 | 73 |
| 73 class VideoStreamFactory | 74 class VideoStreamFactory |
| 74 : public VideoEncoderConfig::VideoStreamFactoryInterface { | 75 : public VideoEncoderConfig::VideoStreamFactoryInterface { |
| 75 public: | 76 public: |
| 76 explicit VideoStreamFactory(size_t num_temporal_layers) | 77 explicit VideoStreamFactory(size_t num_temporal_layers) |
| 77 : num_temporal_layers_(num_temporal_layers) { | 78 : num_temporal_layers_(num_temporal_layers) { |
| 78 EXPECT_GT(num_temporal_layers, 0u); | 79 EXPECT_GT(num_temporal_layers, 0u); |
| 79 } | 80 } |
| 80 | 81 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 VideoCodec codec_config() { | 177 VideoCodec codec_config() { |
| 177 rtc::CritScope lock(&crit_); | 178 rtc::CritScope lock(&crit_); |
| 178 return config_; | 179 return config_; |
| 179 } | 180 } |
| 180 | 181 |
| 181 void BlockNextEncode() { | 182 void BlockNextEncode() { |
| 182 rtc::CritScope lock(&crit_); | 183 rtc::CritScope lock(&crit_); |
| 183 block_next_encode_ = true; | 184 block_next_encode_ = true; |
| 184 } | 185 } |
| 185 | 186 |
| 187 VideoEncoder::ScalingSettings GetScalingSettings() const override { |
| 188 return VideoEncoder::ScalingSettings(true, 1, 2); |
| 189 } |
| 190 |
| 186 void ContinueEncode() { continue_encode_event_.Set(); } | 191 void ContinueEncode() { continue_encode_event_.Set(); } |
| 187 | 192 |
| 188 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, | 193 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, |
| 189 uint32_t timestamp) const { | 194 uint32_t timestamp) const { |
| 190 rtc::CritScope lock(&crit_); | 195 rtc::CritScope lock(&crit_); |
| 191 EXPECT_EQ(timestamp_, timestamp); | 196 EXPECT_EQ(timestamp_, timestamp); |
| 192 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); | 197 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); |
| 193 } | 198 } |
| 194 | 199 |
| 195 private: | 200 private: |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 | 547 |
| 543 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( | 548 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( |
| 544 std::numeric_limits<int>::max()), | 549 std::numeric_limits<int>::max()), |
| 545 frame_width * frame_height); | 550 frame_width * frame_height); |
| 546 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); | 551 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); |
| 547 | 552 |
| 548 frame_width /= 2; | 553 frame_width /= 2; |
| 549 frame_height /= 2; | 554 frame_height /= 2; |
| 550 } | 555 } |
| 551 | 556 |
| 552 // Trigger CPU overuse a one more time. This should not trigger request for | 557 // Trigger CPU overuse one more time. This should not trigger a request for |
| 553 // lower resolution. | 558 // lower resolution. |
| 554 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); | 559 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); |
| 555 video_source_.IncomingCapturedFrame(CreateFrame( | 560 video_source_.IncomingCapturedFrame(CreateFrame( |
| 556 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); | 561 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); |
| 557 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); | 562 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); |
| 558 vie_encoder_->TriggerCpuOveruse(); | 563 vie_encoder_->TriggerCpuOveruse(); |
| 559 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, | 564 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, |
| 560 current_wants.max_pixel_count); | 565 current_wants.max_pixel_count); |
| 561 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up, | 566 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up, |
| 562 current_wants.max_pixel_count_step_up); | 567 current_wants.max_pixel_count_step_up); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 CreateFrame(3, frame_width, frame_height)); | 651 CreateFrame(3, frame_width, frame_height)); |
| 647 sink_.WaitForEncodedFrame(3); | 652 sink_.WaitForEncodedFrame(3); |
| 648 | 653 |
| 649 stats = stats_proxy_->GetStats(); | 654 stats = stats_proxy_->GetStats(); |
| 650 EXPECT_FALSE(stats.cpu_limited_resolution); | 655 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 651 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | 656 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
| 652 | 657 |
| 653 vie_encoder_->Stop(); | 658 vie_encoder_->Stop(); |
| 654 } | 659 } |
| 655 | 660 |
| 661 TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) { |
| 662 const int kTargetBitrateBps = 100000; |
| 663 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 664 |
| 665 int frame_width = 1280; |
| 666 int frame_height = 720; |
| 667 video_source_.IncomingCapturedFrame( |
| 668 CreateFrame(1, frame_width, frame_height)); |
| 669 sink_.WaitForEncodedFrame(1); |
| 670 |
| 671 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
| 672 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 673 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
| 674 |
| 675 vie_encoder_->TriggerCpuOveruse(); |
| 676 |
| 677 video_source_.IncomingCapturedFrame( |
| 678 CreateFrame(2, frame_width, frame_height)); |
| 679 sink_.WaitForEncodedFrame(2); |
| 680 stats = stats_proxy_->GetStats(); |
| 681 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 682 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 683 |
| 684 // Set new source with adaptation still enabled. |
| 685 test::FrameForwarder new_video_source; |
| 686 vie_encoder_->SetSource(&new_video_source, |
| 687 VideoSendStream::DegradationPreference::kBalanced); |
| 688 |
| 689 new_video_source.IncomingCapturedFrame( |
| 690 CreateFrame(3, frame_width, frame_height)); |
| 691 sink_.WaitForEncodedFrame(3); |
| 692 stats = stats_proxy_->GetStats(); |
| 693 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 694 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 695 |
| 696 // Set adaptation disabled. |
| 697 vie_encoder_->SetSource( |
| 698 &new_video_source, |
| 699 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 700 |
| 701 new_video_source.IncomingCapturedFrame( |
| 702 CreateFrame(4, frame_width, frame_height)); |
| 703 sink_.WaitForEncodedFrame(4); |
| 704 stats = stats_proxy_->GetStats(); |
| 705 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 706 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 707 |
| 708 // Set adaptation back to enabled. |
| 709 vie_encoder_->SetSource(&new_video_source, |
| 710 VideoSendStream::DegradationPreference::kBalanced); |
| 711 |
| 712 new_video_source.IncomingCapturedFrame( |
| 713 CreateFrame(5, frame_width, frame_height)); |
| 714 sink_.WaitForEncodedFrame(5); |
| 715 stats = stats_proxy_->GetStats(); |
| 716 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 717 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 718 |
| 719 vie_encoder_->TriggerCpuNormalUsage(); |
| 720 |
| 721 new_video_source.IncomingCapturedFrame( |
| 722 CreateFrame(6, frame_width, frame_height)); |
| 723 sink_.WaitForEncodedFrame(6); |
| 724 stats = stats_proxy_->GetStats(); |
| 725 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 726 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
| 727 |
| 728 vie_encoder_->Stop(); |
| 729 } |
| 730 |
| 731 TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) { |
| 732 const int kTargetBitrateBps = 100000; |
| 733 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 734 |
| 735 int frame_width = 1280; |
| 736 int frame_height = 720; |
| 737 video_source_.IncomingCapturedFrame( |
| 738 CreateFrame(1, frame_width, frame_height)); |
| 739 sink_.WaitForEncodedFrame(1); |
| 740 |
| 741 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
| 742 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 743 EXPECT_FALSE(stats.bw_limited_resolution); |
| 744 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
| 745 |
| 746 // Set new source with adaptation still enabled. |
| 747 test::FrameForwarder new_video_source; |
| 748 vie_encoder_->SetSource(&new_video_source, |
| 749 VideoSendStream::DegradationPreference::kBalanced); |
| 750 |
| 751 new_video_source.IncomingCapturedFrame( |
| 752 CreateFrame(2, frame_width, frame_height)); |
| 753 sink_.WaitForEncodedFrame(2); |
| 754 stats = stats_proxy_->GetStats(); |
| 755 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 756 EXPECT_FALSE(stats.bw_limited_resolution); |
| 757 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
| 758 |
| 759 vie_encoder_->TriggerQualityLow(); |
| 760 |
| 761 new_video_source.IncomingCapturedFrame( |
| 762 CreateFrame(3, frame_width, frame_height)); |
| 763 sink_.WaitForEncodedFrame(3); |
| 764 stats = stats_proxy_->GetStats(); |
| 765 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 766 EXPECT_TRUE(stats.bw_limited_resolution); |
| 767 |
| 768 vie_encoder_->SetSource(&new_video_source, |
| 769 VideoSendStream::DegradationPreference::kBalanced); |
| 770 |
| 771 new_video_source.IncomingCapturedFrame( |
| 772 CreateFrame(4, frame_width, frame_height)); |
| 773 sink_.WaitForEncodedFrame(4); |
| 774 stats = stats_proxy_->GetStats(); |
| 775 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 776 EXPECT_TRUE(stats.bw_limited_resolution); |
| 777 |
| 778 // Set adaptation disabled. |
| 779 vie_encoder_->SetSource( |
| 780 &new_video_source, |
| 781 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 782 |
| 783 new_video_source.IncomingCapturedFrame( |
| 784 CreateFrame(5, frame_width, frame_height)); |
| 785 sink_.WaitForEncodedFrame(5); |
| 786 stats = stats_proxy_->GetStats(); |
| 787 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 788 EXPECT_FALSE(stats.bw_limited_resolution); |
| 789 |
| 790 vie_encoder_->Stop(); |
| 791 } |
| 792 |
| 656 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { | 793 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { |
| 657 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 794 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 658 | 795 |
| 659 // Trigger CPU overuse. | 796 // Trigger CPU overuse. |
| 660 vie_encoder_->TriggerCpuOveruse(); | 797 vie_encoder_->TriggerCpuOveruse(); |
| 661 int frame_width = 1280; | 798 int frame_width = 1280; |
| 662 int frame_height = 720; | 799 int frame_height = 720; |
| 663 | 800 |
| 664 video_source_.IncomingCapturedFrame( | 801 video_source_.IncomingCapturedFrame( |
| 665 CreateFrame(1, frame_width, frame_height)); | 802 CreateFrame(1, frame_width, frame_height)); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720)); | 857 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720)); |
| 721 sink_.WaitForEncodedFrame(1); | 858 sink_.WaitForEncodedFrame(1); |
| 722 | 859 |
| 723 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | 860 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
| 724 EXPECT_EQ(video_encoder_config_.max_bitrate_bps, | 861 EXPECT_EQ(video_encoder_config_.max_bitrate_bps, |
| 725 stats.preferred_media_bitrate_bps); | 862 stats.preferred_media_bitrate_bps); |
| 726 | 863 |
| 727 vie_encoder_->Stop(); | 864 vie_encoder_->Stop(); |
| 728 } | 865 } |
| 729 | 866 |
| 867 TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) { |
| 868 const int kTargetBitrateBps = 100000; |
| 869 int frame_width = 1280; |
| 870 int frame_height = 720; |
| 871 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 872 |
| 873 // Expect no scaling to begin with |
| 874 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); |
| 875 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); |
| 876 |
| 877 // Trigger scale down |
| 878 vie_encoder_->TriggerQualityLow(); |
| 879 video_source_.IncomingCapturedFrame( |
| 880 CreateFrame(1, frame_width, frame_height)); |
| 881 sink_.WaitForEncodedFrame(1); |
| 882 |
| 883 // Expect a scale down. |
| 884 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count); |
| 885 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, |
| 886 frame_width * frame_height); |
| 887 |
| 888 // Set adaptation disabled. |
| 889 test::FrameForwarder new_video_source; |
| 890 vie_encoder_->SetSource( |
| 891 &new_video_source, |
| 892 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 893 |
| 894 // Trigger scale down |
| 895 vie_encoder_->TriggerQualityLow(); |
| 896 new_video_source.IncomingCapturedFrame( |
| 897 CreateFrame(2, frame_width, frame_height)); |
| 898 sink_.WaitForEncodedFrame(2); |
| 899 |
| 900 // Expect no scaling |
| 901 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); |
| 902 |
| 903 // Trigger scale up |
| 904 vie_encoder_->TriggerQualityHigh(); |
| 905 new_video_source.IncomingCapturedFrame( |
| 906 CreateFrame(3, frame_width, frame_height)); |
| 907 sink_.WaitForEncodedFrame(3); |
| 908 |
| 909 // Expect nothing to change, still no scaling |
| 910 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); |
| 911 |
| 912 vie_encoder_->Stop(); |
| 913 } |
| 914 |
| 730 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { | 915 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { |
| 731 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 916 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 732 | 917 |
| 733 int frame_width = 640; | 918 int frame_width = 640; |
| 734 int frame_height = 360; | 919 int frame_height = 360; |
| 735 | 920 |
| 736 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { | 921 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { |
| 737 video_source_.IncomingCapturedFrame( | 922 video_source_.IncomingCapturedFrame( |
| 738 CreateFrame(i, frame_width, frame_height)); | 923 CreateFrame(i, frame_width, frame_height)); |
| 739 sink_.WaitForEncodedFrame(i); | 924 sink_.WaitForEncodedFrame(i); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 751 vie_encoder_->Stop(); | 936 vie_encoder_->Stop(); |
| 752 | 937 |
| 753 stats_proxy_.reset(); | 938 stats_proxy_.reset(); |
| 754 EXPECT_EQ(1, | 939 EXPECT_EQ(1, |
| 755 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); | 940 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); |
| 756 EXPECT_EQ( | 941 EXPECT_EQ( |
| 757 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); | 942 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); |
| 758 } | 943 } |
| 759 | 944 |
| 760 } // namespace webrtc | 945 } // namespace webrtc |
| OLD | NEW |