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

Side by Side Diff: webrtc/video/vie_encoder_unittest.cc

Issue 2398963003: Move usage of QualityScaler to ViEEncoder. (Closed)
Patch Set: rebase Created 4 years, 1 month 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
OLDNEW
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
25 namespace { 27 namespace {
28 // Copied from vie_encoder.cc. Must be kept in sync.
29 static const int kMaxCpuDowngrades = 2;
perkj_webrtc 2016/11/14 07:21:16 Why not keep this in ViEEncoder then? You can eve
kthelgason 2016/11/14 14:36:45 For some reason I did this because I had seen it d
30
26 class TestBuffer : public webrtc::I420Buffer { 31 class TestBuffer : public webrtc::I420Buffer {
27 public: 32 public:
28 TestBuffer(rtc::Event* event, int width, int height) 33 TestBuffer(rtc::Event* event, int width, int height)
29 : I420Buffer(width, height), event_(event) {} 34 : I420Buffer(width, height), event_(event) {}
30 35
31 private: 36 private:
32 friend class rtc::RefCountedObject<TestBuffer>; 37 friend class rtc::RefCountedObject<TestBuffer>;
33 ~TestBuffer() override { 38 ~TestBuffer() override {
34 if (event_) 39 if (event_)
35 event_->Set(); 40 event_->Set();
36 } 41 }
37 rtc::Event* const event_; 42 rtc::Event* const event_;
38 }; 43 };
39 44
40 class ViEEncoderUnderTest : public ViEEncoder { 45 class ViEEncoderUnderTest : public ViEEncoder {
41 public: 46 public:
42 ViEEncoderUnderTest( 47 using ScalingObserverInterface::ScaleReason;
43 SendStatisticsProxy* stats_proxy, 48 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy,
44 const webrtc::VideoSendStream::Config::EncoderSettings& settings) 49 const VideoSendStream::Config::EncoderSettings& settings)
45 : ViEEncoder(1 /* number_of_cores */, 50 : ViEEncoder(1 /* number_of_cores */,
46 stats_proxy, 51 stats_proxy,
47 settings, 52 settings,
48 nullptr /* pre_encode_callback */, 53 nullptr /* pre_encode_callback */,
49 nullptr /* encoder_timing */) {} 54 nullptr /* encoder_timing */) {}
50 55
51 void TriggerCpuOveruse() { 56 void PostTaskAndWait(bool down, ScaleReason reason) {
52 rtc::Event event(false, false); 57 rtc::Event event(false, false);
53 encoder_queue()->PostTask([this, &event] { 58 encoder_queue()->PostTask([this, &event, reason, down] {
54 OveruseDetected(); 59 down ? ScaleDown(reason) : ScaleUp(reason);
55 event.Set(); 60 event.Set();
56 }); 61 });
57 event.Wait(rtc::Event::kForever); 62 RTC_DCHECK(event.Wait(5000));
58 } 63 }
59 64
60 void TriggerCpuNormalUsage() { 65 void TriggerCpuOveruse() { PostTaskAndWait(true, kCpu); }
61 rtc::Event event(false, false); 66
62 encoder_queue()->PostTask([this, &event] { 67 void TriggerCpuNormalUsage() { PostTaskAndWait(false, kCpu); }
63 NormalUsage(); 68
64 event.Set(); 69 void TriggerQualityLow() { PostTaskAndWait(true, kQuality); }
65 }); 70
66 event.Wait(rtc::Event::kForever); 71 void TriggerQualityHigh() { PostTaskAndWait(false, kQuality); }
67 }
68 }; 72 };
69 73
70 } // namespace 74 } // namespace
71 75
72 class ViEEncoderTest : public ::testing::Test { 76 class ViEEncoderTest : public ::testing::Test {
73 public: 77 public:
74 static const int kDefaultTimeoutMs = 30 * 1000; 78 static const int kDefaultTimeoutMs = 30 * 1000;
75 79
76 ViEEncoderTest() 80 ViEEncoderTest()
77 : video_send_config_(VideoSendStream::Config(nullptr)), 81 : video_send_config_(VideoSendStream::Config(nullptr)),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 VideoCodec codec_config() { 131 VideoCodec codec_config() {
128 rtc::CritScope lock(&crit_); 132 rtc::CritScope lock(&crit_);
129 return config_; 133 return config_;
130 } 134 }
131 135
132 void BlockNextEncode() { 136 void BlockNextEncode() {
133 rtc::CritScope lock(&crit_); 137 rtc::CritScope lock(&crit_);
134 block_next_encode_ = true; 138 block_next_encode_ = true;
135 } 139 }
136 140
141 QualityScaler::Settings GetQPThresholds() const override {
142 return QualityScaler::Settings(true, 1, 2);
143 }
144
137 void ContinueEncode() { continue_encode_event_.Set(); } 145 void ContinueEncode() { continue_encode_event_.Set(); }
138 146
139 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, 147 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
140 uint32_t timestamp) const { 148 uint32_t timestamp) const {
141 rtc::CritScope lock(&crit_); 149 rtc::CritScope lock(&crit_);
142 EXPECT_EQ(timestamp_, timestamp); 150 EXPECT_EQ(timestamp_, timestamp);
143 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); 151 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
144 } 152 }
145 153
146 private: 154 private:
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); 412 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
405 413
406 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); 414 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
407 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); 415 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
408 416
409 int frame_width = 1280; 417 int frame_width = 1280;
410 int frame_height = 720; 418 int frame_height = 720;
411 419
412 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should 420 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
413 // request lower resolution. 421 // request lower resolution.
414 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) { 422 for (int i = 1; i <= kMaxCpuDowngrades; ++i) {
415 video_source_.IncomingCapturedFrame( 423 video_source_.IncomingCapturedFrame(
416 CreateFrame(i, frame_width, frame_height)); 424 CreateFrame(i, frame_width, frame_height));
417 sink_.WaitForEncodedFrame(i); 425 sink_.WaitForEncodedFrame(i);
418 426
419 vie_encoder_->TriggerCpuOveruse(); 427 vie_encoder_->TriggerCpuOveruse();
420 428
421 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( 429 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
422 std::numeric_limits<int>::max()), 430 std::numeric_limits<int>::max()),
423 frame_width * frame_height); 431 frame_width * frame_height);
424 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); 432 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
425 433
426 frame_width /= 2; 434 frame_width /= 2;
427 frame_height /= 2; 435 frame_height /= 2;
428 } 436 }
429 437
430 // Trigger CPU overuse a one more time. This should not trigger request for 438 // Trigger CPU overuse one more time. This should not trigger a request for
431 // lower resolution. 439 // lower resolution.
432 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); 440 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
433 video_source_.IncomingCapturedFrame(CreateFrame( 441 video_source_.IncomingCapturedFrame(
434 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); 442 CreateFrame(kMaxCpuDowngrades + 1, frame_width, frame_height));
435 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); 443 sink_.WaitForEncodedFrame(kMaxCpuDowngrades + 1);
436 vie_encoder_->TriggerCpuOveruse(); 444 vie_encoder_->TriggerCpuOveruse();
437 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, 445 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
438 current_wants.max_pixel_count); 446 current_wants.max_pixel_count);
439 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up, 447 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
440 current_wants.max_pixel_count_step_up); 448 current_wants.max_pixel_count_step_up);
441 449
442 // Trigger CPU normal use. 450 // Trigger CPU normal use.
443 vie_encoder_->TriggerCpuNormalUsage(); 451 vie_encoder_->TriggerCpuNormalUsage();
444 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); 452 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
445 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0), 453 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 CreateFrame(3, frame_width, frame_height)); 534 CreateFrame(3, frame_width, frame_height));
527 sink_.WaitForEncodedFrame(3); 535 sink_.WaitForEncodedFrame(3);
528 536
529 stats = stats_proxy_->GetStats(); 537 stats = stats_proxy_->GetStats();
530 EXPECT_FALSE(stats.cpu_limited_resolution); 538 EXPECT_FALSE(stats.cpu_limited_resolution);
531 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); 539 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
532 540
533 vie_encoder_->Stop(); 541 vie_encoder_->Stop();
534 } 542 }
535 543
544 TEST_F(ViEEncoderTest, SwitchingSourceKeepsAdaptation) {
perkj_webrtc 2016/11/14 07:21:16 This looks like the same test as StatsTracksAdapta
kthelgason 2016/11/14 14:36:45 Ah, that's a rebase artifact. The test got duplica
545 const int kTargetBitrateBps = 100000;
546 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
547
548 int frame_width = 1280;
549 int frame_height = 720;
550 video_source_.IncomingCapturedFrame(
551 CreateFrame(1, frame_width, frame_height));
552 sink_.WaitForEncodedFrame(1);
553
554 VideoSendStream::Stats stats = stats_proxy_->GetStats();
555 EXPECT_FALSE(stats.cpu_limited_resolution);
556 EXPECT_FALSE(stats.bw_limited_resolution);
557 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
558
559 // Set new source with adaptation still enabled.
560 test::FrameForwarder new_video_source;
561 vie_encoder_->SetSource(&new_video_source,
562 VideoSendStream::DegradationPreference::kBalanced);
563
564 new_video_source.IncomingCapturedFrame(
565 CreateFrame(2, frame_width, frame_height));
566 sink_.WaitForEncodedFrame(2);
567 stats = stats_proxy_->GetStats();
568 EXPECT_FALSE(stats.cpu_limited_resolution);
569 EXPECT_FALSE(stats.bw_limited_resolution);
570 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
571
572 vie_encoder_->TriggerQualityLow();
573
574 new_video_source.IncomingCapturedFrame(
575 CreateFrame(3, frame_width, frame_height));
576 sink_.WaitForEncodedFrame(3);
577 stats = stats_proxy_->GetStats();
578 EXPECT_FALSE(stats.cpu_limited_resolution);
579 EXPECT_TRUE(stats.bw_limited_resolution);
580
581 vie_encoder_->SetSource(&new_video_source,
582 VideoSendStream::DegradationPreference::kBalanced);
583
584 new_video_source.IncomingCapturedFrame(
585 CreateFrame(4, frame_width, frame_height));
586 sink_.WaitForEncodedFrame(4);
587 stats = stats_proxy_->GetStats();
588 EXPECT_FALSE(stats.cpu_limited_resolution);
589 EXPECT_TRUE(stats.bw_limited_resolution);
590
591 // Set adaptation disabled.
592 vie_encoder_->SetSource(
593 &new_video_source,
594 VideoSendStream::DegradationPreference::kMaintainResolution);
595
596 new_video_source.IncomingCapturedFrame(
597 CreateFrame(5, frame_width, frame_height));
598 sink_.WaitForEncodedFrame(5);
599 stats = stats_proxy_->GetStats();
600 EXPECT_FALSE(stats.cpu_limited_resolution);
601 EXPECT_FALSE(stats.bw_limited_resolution);
602
603 vie_encoder_->Stop();
604 }
605
536 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { 606 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
537 const int kTargetBitrateBps = 100000; 607 const int kTargetBitrateBps = 100000;
538 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); 608 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
539 609
540 // Trigger CPU overuse. 610 // Trigger CPU overuse.
541 vie_encoder_->TriggerCpuOveruse(); 611 vie_encoder_->TriggerCpuOveruse();
542 int frame_width = 1280; 612 int frame_width = 1280;
543 int frame_height = 720; 613 int frame_height = 720;
544 614
545 video_source_.IncomingCapturedFrame( 615 video_source_.IncomingCapturedFrame(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 video_source_.IncomingCapturedFrame( 658 video_source_.IncomingCapturedFrame(
589 CreateFrame(5, frame_width, frame_height)); 659 CreateFrame(5, frame_width, frame_height));
590 sink_.WaitForEncodedFrame(5); 660 sink_.WaitForEncodedFrame(5);
591 stats = stats_proxy_->GetStats(); 661 stats = stats_proxy_->GetStats();
592 EXPECT_FALSE(stats.cpu_limited_resolution); 662 EXPECT_FALSE(stats.cpu_limited_resolution);
593 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); 663 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
594 664
595 vie_encoder_->Stop(); 665 vie_encoder_->Stop();
596 } 666 }
597 667
668 TEST_F(ViEEncoderTest, StatsTracksQualityAdaptationStatsWhenSwitchingSource) {
669 const int kTargetBitrateBps = 100000;
670 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
671
672 // Trigger CPU overuse.
673 vie_encoder_->TriggerQualityLow();
674 int frame_width = 1280;
675 int frame_height = 720;
676
677 video_source_.IncomingCapturedFrame(
678 CreateFrame(1, frame_width, frame_height));
679 sink_.WaitForEncodedFrame(1);
680
681 VideoSendStream::Stats stats = stats_proxy_->GetStats();
682 EXPECT_TRUE(stats.bw_limited_resolution);
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(2, frame_width, frame_height));
691 sink_.WaitForEncodedFrame(2);
692 stats = stats_proxy_->GetStats();
693 EXPECT_TRUE(stats.bw_limited_resolution);
694
695 // Set adaptation disabled.
696 vie_encoder_->SetSource(
697 &new_video_source,
698 VideoSendStream::DegradationPreference::kMaintainResolution);
699
700 new_video_source.IncomingCapturedFrame(
701 CreateFrame(3, frame_width, frame_height));
702 sink_.WaitForEncodedFrame(3);
703 stats = stats_proxy_->GetStats();
704 EXPECT_FALSE(stats.bw_limited_resolution);
705
706 // Switch back the source with adaptation enabled.
707 vie_encoder_->SetSource(&video_source_,
708 VideoSendStream::DegradationPreference::kBalanced);
709 video_source_.IncomingCapturedFrame(
710 CreateFrame(4, frame_width, frame_height));
711 sink_.WaitForEncodedFrame(4);
712 stats = stats_proxy_->GetStats();
713 EXPECT_TRUE(stats.bw_limited_resolution);
714
715 // Trigger CPU normal usage.
716 vie_encoder_->TriggerQualityHigh();
717 video_source_.IncomingCapturedFrame(
718 CreateFrame(5, frame_width, frame_height));
719 sink_.WaitForEncodedFrame(5);
720 stats = stats_proxy_->GetStats();
721 EXPECT_FALSE(stats.bw_limited_resolution);
722
723 vie_encoder_->Stop();
724 }
725
598 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { 726 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
599 const int kTargetBitrateBps = 100000; 727 const int kTargetBitrateBps = 100000;
600 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); 728 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
601 729
602 int frame_width = 640; 730 int frame_width = 640;
603 int frame_height = 360; 731 int frame_height = 360;
604 732
605 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { 733 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
606 video_source_.IncomingCapturedFrame( 734 video_source_.IncomingCapturedFrame(
607 CreateFrame(i, frame_width, frame_height)); 735 CreateFrame(i, frame_width, frame_height));
(...skipping 12 matching lines...) Expand all
620 vie_encoder_->Stop(); 748 vie_encoder_->Stop();
621 749
622 stats_proxy_.reset(); 750 stats_proxy_.reset();
623 EXPECT_EQ(1, 751 EXPECT_EQ(1,
624 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); 752 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
625 EXPECT_EQ( 753 EXPECT_EQ(
626 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); 754 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
627 } 755 }
628 756
629 } // namespace webrtc 757 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698