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 <utility> | 11 #include <utility> |
12 | 12 |
13 #include "webrtc/base/logging.h" | 13 #include "webrtc/base/logging.h" |
14 #include "webrtc/system_wrappers/include/metrics_default.h" | |
14 #include "webrtc/test/encoder_settings.h" | 15 #include "webrtc/test/encoder_settings.h" |
15 #include "webrtc/test/fake_encoder.h" | 16 #include "webrtc/test/fake_encoder.h" |
16 #include "webrtc/test/frame_generator.h" | 17 #include "webrtc/test/frame_generator.h" |
17 #include "webrtc/test/gtest.h" | 18 #include "webrtc/test/gtest.h" |
18 #include "webrtc/video/send_statistics_proxy.h" | 19 #include "webrtc/video/send_statistics_proxy.h" |
19 #include "webrtc/video/vie_encoder.h" | 20 #include "webrtc/video/vie_encoder.h" |
20 | 21 |
21 namespace webrtc { | 22 namespace webrtc { |
22 | 23 |
24 namespace { | |
25 class TestBuffer : public webrtc::I420Buffer { | |
26 public: | |
27 TestBuffer(rtc::Event* event, int width, int height) | |
28 : I420Buffer(width, height), event_(event) {} | |
29 | |
30 private: | |
31 friend class rtc::RefCountedObject<TestBuffer>; | |
32 ~TestBuffer() override { | |
33 if (event_) | |
34 event_->Set(); | |
35 } | |
36 rtc::Event* const event_; | |
37 }; | |
38 | |
39 class ViEEncoderUnderTest : public ViEEncoder { | |
40 public: | |
41 ViEEncoderUnderTest( | |
42 SendStatisticsProxy* stats_proxy, | |
43 const webrtc::VideoSendStream::Config::EncoderSettings& settings) | |
44 : ViEEncoder(1 /* number_of_cores */, | |
45 stats_proxy, | |
46 settings, | |
47 nullptr /* pre_encode_callback */, | |
48 nullptr /* encoder_timing */) {} | |
49 | |
50 void TriggerCpuOveruse() { | |
51 rtc::Event event(false, false); | |
52 encoder_queue()->PostTask([this, &event] { | |
53 OveruseDetected(); | |
54 event.Set(); | |
55 }); | |
56 event.Wait(rtc::Event::kForever); | |
57 } | |
58 | |
59 void TriggerCpuNormalUsage() { | |
60 rtc::Event event(false, false); | |
61 encoder_queue()->PostTask([this, &event] { | |
62 NormalUsage(); | |
63 event.Set(); | |
64 }); | |
65 event.Wait(rtc::Event::kForever); | |
66 } | |
67 | |
68 bool IsOveruseFrameDetectionEnabled() { | |
69 bool result = false; | |
70 rtc::Event event(false, false); | |
71 encoder_queue()->PostTask([this, &event, &result] { | |
72 result = OveruseFrameDetectionEnabled(); | |
73 event.Set(); | |
74 }); | |
75 event.Wait(rtc::Event::kForever); | |
76 return result; | |
77 } | |
78 }; | |
79 | |
80 } // namespace | |
81 | |
23 class ViEEncoderTest : public ::testing::Test { | 82 class ViEEncoderTest : public ::testing::Test { |
24 public: | 83 public: |
25 static const int kDefaultTimeoutMs = 30 * 1000; | 84 static const int kDefaultTimeoutMs = 30 * 1000; |
26 | 85 |
27 ViEEncoderTest() | 86 ViEEncoderTest() |
28 : video_send_config_(VideoSendStream::Config(nullptr)), | 87 : video_send_config_(VideoSendStream::Config(nullptr)), |
29 codec_width_(320), | 88 codec_width_(320), |
30 codec_height_(240), | 89 codec_height_(240), |
31 fake_encoder_(), | 90 fake_encoder_(), |
32 stats_proxy_(Clock::GetRealTimeClock(), | 91 stats_proxy_(new SendStatisticsProxy( |
33 video_send_config_, | 92 Clock::GetRealTimeClock(), |
34 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo), | 93 video_send_config_, |
94 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)), | |
35 sink_(&fake_encoder_) {} | 95 sink_(&fake_encoder_) {} |
36 | 96 |
37 void SetUp() override { | 97 void SetUp() override { |
38 video_send_config_ = VideoSendStream::Config(nullptr); | 98 video_send_config_ = VideoSendStream::Config(nullptr); |
39 video_send_config_.encoder_settings.encoder = &fake_encoder_; | 99 video_send_config_.encoder_settings.encoder = &fake_encoder_; |
40 video_send_config_.encoder_settings.payload_name = "FAKE"; | 100 video_send_config_.encoder_settings.payload_name = "FAKE"; |
41 video_send_config_.encoder_settings.payload_type = 125; | 101 video_send_config_.encoder_settings.payload_type = 125; |
42 | 102 |
43 VideoEncoderConfig video_encoder_config; | 103 VideoEncoderConfig video_encoder_config; |
44 test::FillEncoderConfiguration(1, &video_encoder_config); | 104 test::FillEncoderConfiguration(1, &video_encoder_config); |
45 vie_encoder_.reset(new ViEEncoder( | 105 vie_encoder_.reset(new ViEEncoderUnderTest( |
46 1 /* number_of_cores */, &stats_proxy_, | 106 stats_proxy_.get(), video_send_config_.encoder_settings)); |
47 video_send_config_.encoder_settings, nullptr /* pre_encode_callback */, | 107 vie_encoder_->SetSink(&sink_, false /* rotation_applied */); |
48 nullptr /* overuse_callback */, nullptr /* encoder_timing */)); | 108 vie_encoder_->SetSource(&video_source_, |
49 vie_encoder_->SetSink(&sink_); | 109 false /* disable_resolution_scaling */); |
50 vie_encoder_->SetSource(&video_source_); | |
51 vie_encoder_->SetStartBitrate(10000); | 110 vie_encoder_->SetStartBitrate(10000); |
52 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), 1440); | 111 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), 1440); |
53 } | 112 } |
54 | 113 |
55 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const { | 114 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const { |
56 class TestBuffer : public webrtc::I420Buffer { | 115 class TestBuffer : public webrtc::I420Buffer { |
57 public: | 116 public: |
58 TestBuffer(rtc::Event* event, int width, int height) | 117 TestBuffer(rtc::Event* event, int width, int height) |
59 : I420Buffer(width, height), event_(event) {} | 118 : I420Buffer(width, height), event_(event) {} |
60 | 119 |
61 private: | 120 private: |
62 friend class rtc::RefCountedObject<TestBuffer>; | 121 friend class rtc::RefCountedObject<TestBuffer>; |
63 ~TestBuffer() override { | 122 ~TestBuffer() override { |
64 if (event_) | 123 if (event_) |
65 event_->Set(); | 124 event_->Set(); |
66 } | 125 } |
67 rtc::Event* const event_; | 126 rtc::Event* const event_; |
68 }; | 127 }; |
69 | 128 |
70 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>( | 129 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>( |
71 destruction_event, codec_width_, codec_height_), | 130 destruction_event, codec_width_, codec_height_), |
72 99, 99, kVideoRotation_0); | 131 99, 99, kVideoRotation_0); |
73 frame.set_ntp_time_ms(ntp_ts); | 132 frame.set_ntp_time_ms(ntp_ts); |
74 return frame; | 133 return frame; |
75 } | 134 } |
76 | 135 |
136 VideoFrame CreateFrame(int64_t ntp_ts, int width, int height) const { | |
137 VideoFrame frame( | |
138 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99, | |
139 kVideoRotation_0); | |
140 frame.set_ntp_time_ms(ntp_ts); | |
141 return frame; | |
142 } | |
143 | |
77 class TestEncoder : public test::FakeEncoder { | 144 class TestEncoder : public test::FakeEncoder { |
78 public: | 145 public: |
79 TestEncoder() | 146 TestEncoder() |
80 : FakeEncoder(Clock::GetRealTimeClock()), | 147 : FakeEncoder(Clock::GetRealTimeClock()), |
81 continue_encode_event_(false, false) {} | 148 continue_encode_event_(false, false) {} |
82 | 149 |
83 VideoCodec codec_config() { | 150 VideoCodec codec_config() { |
84 rtc::CritScope lock(&crit_); | 151 rtc::CritScope lock(&crit_); |
85 return config_; | 152 return config_; |
86 } | 153 } |
(...skipping 18 matching lines...) Expand all Loading... | |
105 const std::vector<FrameType>* frame_types) override { | 172 const std::vector<FrameType>* frame_types) override { |
106 bool block_encode; | 173 bool block_encode; |
107 { | 174 { |
108 rtc::CritScope lock(&crit_); | 175 rtc::CritScope lock(&crit_); |
109 EXPECT_GT(input_image.timestamp(), timestamp_); | 176 EXPECT_GT(input_image.timestamp(), timestamp_); |
110 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_); | 177 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_); |
111 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90); | 178 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90); |
112 | 179 |
113 timestamp_ = input_image.timestamp(); | 180 timestamp_ = input_image.timestamp(); |
114 ntp_time_ms_ = input_image.ntp_time_ms(); | 181 ntp_time_ms_ = input_image.ntp_time_ms(); |
182 last_input_width_ = input_image.width(); | |
183 last_input_height_ = input_image.height(); | |
115 block_encode = block_next_encode_; | 184 block_encode = block_next_encode_; |
116 block_next_encode_ = false; | 185 block_next_encode_ = false; |
117 } | 186 } |
118 int32_t result = | 187 int32_t result = |
119 FakeEncoder::Encode(input_image, codec_specific_info, frame_types); | 188 FakeEncoder::Encode(input_image, codec_specific_info, frame_types); |
120 if (block_encode) | 189 if (block_encode) |
121 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs)); | 190 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs)); |
122 return result; | 191 return result; |
123 } | 192 } |
124 | 193 |
125 | |
126 | |
127 rtc::CriticalSection crit_; | 194 rtc::CriticalSection crit_; |
128 bool block_next_encode_ = false; | 195 bool block_next_encode_ = false; |
129 rtc::Event continue_encode_event_; | 196 rtc::Event continue_encode_event_; |
130 uint32_t timestamp_ = 0; | 197 uint32_t timestamp_ = 0; |
131 int64_t ntp_time_ms_ = 0; | 198 int64_t ntp_time_ms_ = 0; |
199 int last_input_width_ = 0; | |
200 int last_input_height_ = 0; | |
132 }; | 201 }; |
133 | 202 |
134 class TestSink : public ViEEncoder::EncoderSink { | 203 class TestSink : public ViEEncoder::EncoderSink { |
135 public: | 204 public: |
136 explicit TestSink(TestEncoder* test_encoder) | 205 explicit TestSink(TestEncoder* test_encoder) |
137 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {} | 206 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {} |
138 | 207 |
139 void WaitForEncodedFrame(int64_t expected_ntp_time) { | 208 void WaitForEncodedFrame(int64_t expected_ntp_time) { |
140 uint32_t timestamp = 0; | 209 uint32_t timestamp = 0; |
141 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); | 210 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 uint32_t timestamp_ = 0; | 254 uint32_t timestamp_ = 0; |
186 bool expect_frames_ = true; | 255 bool expect_frames_ = true; |
187 int number_of_reconfigurations_ = 0; | 256 int number_of_reconfigurations_ = 0; |
188 int min_transmit_bitrate_bps_ = 0; | 257 int min_transmit_bitrate_bps_ = 0; |
189 }; | 258 }; |
190 | 259 |
191 VideoSendStream::Config video_send_config_; | 260 VideoSendStream::Config video_send_config_; |
192 int codec_width_; | 261 int codec_width_; |
193 int codec_height_; | 262 int codec_height_; |
194 TestEncoder fake_encoder_; | 263 TestEncoder fake_encoder_; |
195 SendStatisticsProxy stats_proxy_; | 264 std::unique_ptr<SendStatisticsProxy> stats_proxy_; |
196 TestSink sink_; | 265 TestSink sink_; |
197 test::FrameForwarder video_source_; | 266 test::FrameForwarder video_source_; |
198 std::unique_ptr<ViEEncoder> vie_encoder_; | 267 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_; |
199 }; | 268 }; |
200 | 269 |
201 TEST_F(ViEEncoderTest, EncodeOneFrame) { | 270 TEST_F(ViEEncoderTest, EncodeOneFrame) { |
202 const int kTargetBitrateBps = 100000; | 271 const int kTargetBitrateBps = 100000; |
203 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 272 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
204 rtc::Event frame_destroyed_event(false, false); | 273 rtc::Event frame_destroyed_event(false, false); |
205 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event)); | 274 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event)); |
206 sink_.WaitForEncodedFrame(1); | 275 sink_.WaitForEncodedFrame(1); |
207 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs)); | 276 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs)); |
208 vie_encoder_->Stop(); | 277 vie_encoder_->Stop(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 // with the encoder thread. | 396 // with the encoder thread. |
328 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr)); | 397 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr)); |
329 sink_.WaitForEncodedFrame(2); | 398 sink_.WaitForEncodedFrame(2); |
330 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width); | 399 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width); |
331 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height); | 400 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height); |
332 EXPECT_EQ(3, sink_.number_of_reconfigurations()); | 401 EXPECT_EQ(3, sink_.number_of_reconfigurations()); |
333 | 402 |
334 vie_encoder_->Stop(); | 403 vie_encoder_->Stop(); |
335 } | 404 } |
336 | 405 |
406 TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) { | |
407 EXPECT_EQ(1u, video_source_.number_of_sinks()); | |
408 test::FrameForwarder new_video_source; | |
409 vie_encoder_->SetSource(&new_video_source, false); | |
410 EXPECT_EQ(0u, video_source_.number_of_sinks()); | |
411 EXPECT_EQ(1u, new_video_source.number_of_sinks()); | |
412 | |
413 vie_encoder_->Stop(); | |
414 } | |
415 | |
416 TEST_F(ViEEncoderTest, SinkWantsRotationApplied) { | |
417 EXPECT_FALSE(video_source_.current_sink_wants().rotation_applied); | |
418 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/); | |
419 EXPECT_TRUE(video_source_.current_sink_wants().rotation_applied); | |
420 vie_encoder_->Stop(); | |
421 } | |
422 | |
423 TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) { | |
424 const int kTargetBitrateBps = 100000; | |
425 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | |
426 | |
427 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count); | |
428 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count_step_up); | |
429 | |
430 int frame_width = 1280; | |
431 int frame_height = 720; | |
432 | |
433 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should | |
434 // request | |
435 // lower resolution. | |
åsapersson
2016/10/24 07:54:06
see spacing
perkj_webrtc
2016/10/26 16:40:17
Done.
| |
436 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) { | |
437 video_source_.IncomingCapturedFrame( | |
438 CreateFrame(i, frame_width, frame_height)); | |
439 sink_.WaitForEncodedFrame(i); | |
440 | |
441 vie_encoder_->TriggerCpuOveruse(); | |
442 | |
443 EXPECT_LT(video_source_.current_sink_wants().max_pixel_count.value_or(0), | |
444 frame_width * frame_height); | |
445 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count_step_up); | |
446 | |
447 frame_width /= 2; | |
448 frame_height /= 2; | |
449 } | |
450 | |
451 // Trigger CPU overuse a one more time. This should not trigger a request for | |
452 // lower resolution. | |
453 rtc::VideoSinkWants current_wants = video_source_.current_sink_wants(); | |
454 video_source_.IncomingCapturedFrame(CreateFrame( | |
455 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); | |
456 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); | |
457 vie_encoder_->TriggerCpuOveruse(); | |
458 EXPECT_EQ(video_source_.current_sink_wants().max_pixel_count, | |
459 current_wants.max_pixel_count); | |
460 EXPECT_EQ(video_source_.current_sink_wants().max_pixel_count_step_up, | |
461 current_wants.max_pixel_count_step_up); | |
462 | |
463 // Trigger CPU normal use. | |
464 vie_encoder_->TriggerCpuNormalUsage(); | |
465 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count); | |
466 EXPECT_EQ( | |
467 video_source_.current_sink_wants().max_pixel_count_step_up.value_or(0), | |
468 frame_width * frame_height); | |
469 | |
470 vie_encoder_->Stop(); | |
471 } | |
472 | |
473 TEST_F(ViEEncoderTest, | |
474 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) { | |
475 const int kTargetBitrateBps = 100000; | |
476 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | |
477 | |
478 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count); | |
479 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count_step_up); | |
480 EXPECT_TRUE(vie_encoder_->IsOveruseFrameDetectionEnabled()); | |
481 | |
482 int frame_width = 1280; | |
483 int frame_height = 720; | |
484 | |
485 // Trigger CPU overuse. | |
486 vie_encoder_->TriggerCpuOveruse(); | |
487 | |
488 video_source_.IncomingCapturedFrame( | |
489 CreateFrame(1, frame_width, frame_height)); | |
490 sink_.WaitForEncodedFrame(1); | |
491 EXPECT_LT(video_source_.current_sink_wants().max_pixel_count.value_or(0), | |
492 frame_width * frame_height); | |
493 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count_step_up); | |
494 | |
495 // Set new source. | |
496 test::FrameForwarder new_video_source; | |
497 vie_encoder_->SetSource(&new_video_source, | |
498 true /* disable_resolution_scaling*/); | |
499 EXPECT_FALSE(vie_encoder_->IsOveruseFrameDetectionEnabled()); | |
500 | |
501 EXPECT_FALSE(new_video_source.current_sink_wants().max_pixel_count); | |
502 EXPECT_FALSE(new_video_source.current_sink_wants().max_pixel_count_step_up); | |
503 | |
504 new_video_source.IncomingCapturedFrame( | |
505 CreateFrame(3, frame_width, frame_height)); | |
506 sink_.WaitForEncodedFrame(3); | |
507 EXPECT_FALSE(new_video_source.current_sink_wants().max_pixel_count); | |
508 EXPECT_FALSE(new_video_source.current_sink_wants().max_pixel_count_step_up); | |
509 | |
510 // Calling SetSource with resolution scaling enabled apply the old SinkWants. | |
511 vie_encoder_->SetSource(&new_video_source, | |
512 false /* disable_resolution_scaling*/); | |
513 EXPECT_LT(new_video_source.current_sink_wants().max_pixel_count.value_or(0), | |
514 frame_width * frame_height); | |
515 EXPECT_FALSE(new_video_source.current_sink_wants().max_pixel_count_step_up); | |
516 | |
517 vie_encoder_->Stop(); | |
518 } | |
519 | |
520 TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) { | |
521 const int kTargetBitrateBps = 100000; | |
522 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | |
523 | |
524 int frame_width = 1280; | |
525 int frame_height = 720; | |
526 | |
527 video_source_.IncomingCapturedFrame( | |
528 CreateFrame(1, frame_width, frame_height)); | |
529 sink_.WaitForEncodedFrame(1); | |
530 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | |
531 EXPECT_FALSE(stats.cpu_limited_resolution); | |
532 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); | |
533 | |
534 // Trigger CPU overuse. | |
535 vie_encoder_->TriggerCpuOveruse(); | |
536 video_source_.IncomingCapturedFrame( | |
537 CreateFrame(2, frame_width, frame_height)); | |
538 sink_.WaitForEncodedFrame(2); | |
539 | |
540 stats = stats_proxy_->GetStats(); | |
541 EXPECT_TRUE(stats.cpu_limited_resolution); | |
542 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
543 | |
544 // Trigger CPU normal use. | |
545 vie_encoder_->TriggerCpuNormalUsage(); | |
546 video_source_.IncomingCapturedFrame( | |
547 CreateFrame(3, frame_width, frame_height)); | |
548 sink_.WaitForEncodedFrame(3); | |
549 | |
550 stats = stats_proxy_->GetStats(); | |
551 EXPECT_FALSE(stats.cpu_limited_resolution); | |
552 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | |
553 | |
554 vie_encoder_->Stop(); | |
555 } | |
556 | |
557 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { | |
558 const int kTargetBitrateBps = 100000; | |
559 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | |
560 | |
561 // Trigger CPU overuse. | |
562 vie_encoder_->TriggerCpuOveruse(); | |
563 int frame_width = 1280; | |
564 int frame_height = 720; | |
565 | |
566 video_source_.IncomingCapturedFrame( | |
567 CreateFrame(1, frame_width, frame_height)); | |
568 sink_.WaitForEncodedFrame(1); | |
569 | |
570 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | |
571 EXPECT_TRUE(stats.cpu_limited_resolution); | |
572 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
573 | |
574 // Set new source with adaptation still enabled. | |
575 test::FrameForwarder new_video_source; | |
576 vie_encoder_->SetSource(&new_video_source, | |
577 false /* disable_resolution_scaling*/); | |
578 | |
579 new_video_source.IncomingCapturedFrame( | |
580 CreateFrame(2, frame_width, frame_height)); | |
581 sink_.WaitForEncodedFrame(2); | |
582 stats = stats_proxy_->GetStats(); | |
583 EXPECT_TRUE(stats.cpu_limited_resolution); | |
584 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
585 | |
586 // Set adaptation disabled. | |
587 vie_encoder_->SetSource(&new_video_source, | |
588 true /* disable_resolution_scaling*/); | |
589 new_video_source.IncomingCapturedFrame( | |
590 CreateFrame(3, frame_width, frame_height)); | |
591 sink_.WaitForEncodedFrame(3); | |
592 stats = stats_proxy_->GetStats(); | |
593 EXPECT_FALSE(stats.cpu_limited_resolution); | |
594 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
595 | |
596 // Switch back the source with adaptation enabled. | |
597 vie_encoder_->SetSource(&video_source_, | |
598 false /* disable_resolution_scaling*/); | |
599 video_source_.IncomingCapturedFrame( | |
600 CreateFrame(4, frame_width, frame_height)); | |
601 sink_.WaitForEncodedFrame(4); | |
602 stats = stats_proxy_->GetStats(); | |
603 EXPECT_TRUE(stats.cpu_limited_resolution); | |
604 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
605 | |
606 // Trigger CPU normal usage. | |
607 vie_encoder_->TriggerCpuNormalUsage(); | |
608 video_source_.IncomingCapturedFrame( | |
609 CreateFrame(5, frame_width, frame_height)); | |
610 sink_.WaitForEncodedFrame(5); | |
611 stats = stats_proxy_->GetStats(); | |
612 EXPECT_FALSE(stats.cpu_limited_resolution); | |
613 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | |
614 | |
615 vie_encoder_->Stop(); | |
616 } | |
617 | |
618 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { | |
619 const int kTargetBitrateBps = 100000; | |
620 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | |
621 | |
622 int frame_width = 640; | |
623 int frame_height = 360; | |
624 | |
625 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredUMASamples; ++i) { | |
626 video_source_.IncomingCapturedFrame( | |
627 CreateFrame(i, frame_width, frame_height)); | |
628 sink_.WaitForEncodedFrame(i); | |
629 } | |
630 | |
631 vie_encoder_->TriggerCpuOveruse(); | |
632 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredUMASamples; ++i) { | |
633 video_source_.IncomingCapturedFrame( | |
634 CreateFrame(SendStatisticsProxy::kMinRequiredUMASamples + i, | |
635 frame_width, frame_height)); | |
636 sink_.WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredUMASamples + i); | |
637 } | |
638 | |
639 vie_encoder_->Stop(); | |
640 | |
641 stats_proxy_.reset(); | |
642 EXPECT_EQ(1, | |
643 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); | |
644 EXPECT_EQ( | |
645 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); | |
646 } | |
647 | |
337 } // namespace webrtc | 648 } // namespace webrtc |
OLD | NEW |