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