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