diff --git a/video/overuse_frame_detector.cc b/video/overuse_frame_detector.cc index 0dfc29ef4e..95aaf59f17 100644 --- a/video/overuse_frame_detector.cc +++ b/video/overuse_frame_detector.cc @@ -249,6 +249,14 @@ class SendProcessingUsage2 : public OveruseFrameDetector::ProcessingUsage { absl::optional encode_duration_us) override { if (encode_duration_us) { if (prev_time_us_ != -1) { + if (capture_time_us < prev_time_us_) { + // The weighting in AddSample assumes that samples are processed with + // non-decreasing measurement timestamps. We could implement + // appropriate weights for samples arriving late, but since it is a + // rare case, keep things simple, by just pushing those measurements a + // bit forward in time. + capture_time_us = prev_time_us_; + } AddSample(1e-6 * (*encode_duration_us), 1e-6 * (capture_time_us - prev_time_us_)); } diff --git a/video/overuse_frame_detector_unittest.cc b/video/overuse_frame_detector_unittest.cc index 41db0f00f6..e65dc26495 100644 --- a/video/overuse_frame_detector_unittest.cc +++ b/video/overuse_frame_detector_unittest.cc @@ -890,4 +890,19 @@ TEST_F(OveruseFrameDetectorTest2, NoOveruseForRandomFrameIntervalWithReset) { EXPECT_LE(UsagePercent(), InitialUsage() + 5); } +TEST_F(OveruseFrameDetectorTest2, ToleratesOutOfOrderFrames) { + overuse_detector_->SetOptions(options_); + // Represents a cpu utilization close to 100%. First input frame results in + // three encoded frames, and the last of those isn't finished until after the + // first encoded frame corresponding to the next input frame. + const int kEncodeTimeUs = 30 * rtc::kNumMicrosecsPerMillisec; + const int kCaptureTimesMs[] = { 33, 33, 66, 33 }; + + for (int capture_time_ms : kCaptureTimesMs) { + overuse_detector_->FrameSent( + 0, 0, capture_time_ms * rtc::kNumMicrosecsPerMillisec, kEncodeTimeUs); + } + EXPECT_GE(UsagePercent(), InitialUsage()); +} + } // namespace webrtc