mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00

This class looks first and foremost on frame intervals instead of number of frames withing the averaging window. This leads to higher prevision values than the bucketized methods of RateTracker and RateStatistics. It is also design to return floating point values, for cases where we are running at low fps - such as a somewhat common 30/4 = 7.5fps. Bug: webrtc:10481 Change-Id: I41c36caaf2b7b46edf7927c8dd08e6cde3380884 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148593 Reviewed-by: Magnus Flodman <mflodman@webrtc.org> Commit-Queue: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28857}
103 lines
3.5 KiB
C++
103 lines
3.5 KiB
C++
/*
|
|
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "common_video/frame_rate_estimator.h"
|
|
|
|
#include "system_wrappers/include/clock.h"
|
|
#include "test/gmock.h"
|
|
#include "test/gtest.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
constexpr TimeDelta kDefaultWindow = TimeDelta::Millis<1000>();
|
|
}
|
|
|
|
class FrameRateEstimatorTest : public ::testing::Test {
|
|
public:
|
|
FrameRateEstimatorTest() : clock_(123), estimator_(kDefaultWindow) {}
|
|
|
|
protected:
|
|
SimulatedClock clock_;
|
|
FrameRateEstimator estimator_;
|
|
};
|
|
|
|
TEST_F(FrameRateEstimatorTest, NoEstimateWithLessThanTwoFrames) {
|
|
EXPECT_FALSE(estimator_.GetAverageFps());
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
EXPECT_FALSE(estimator_.GetAverageFps());
|
|
clock_.AdvanceTime(TimeDelta::ms(33));
|
|
EXPECT_FALSE(estimator_.GetAverageFps());
|
|
}
|
|
|
|
TEST_F(FrameRateEstimatorTest, NoEstimateWithZeroSpan) {
|
|
// Two frames, but they are spanning 0ms so can't estimate frame rate.
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
EXPECT_FALSE(estimator_.GetAverageFps());
|
|
}
|
|
|
|
TEST_F(FrameRateEstimatorTest, SingleSpanFps) {
|
|
const double kExpectedFps = 30.0;
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
clock_.AdvanceTime(TimeDelta::seconds(1) / kExpectedFps);
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
EXPECT_NEAR(*estimator_.GetAverageFps(), kExpectedFps, 0.001);
|
|
}
|
|
|
|
TEST_F(FrameRateEstimatorTest, AverageFps) {
|
|
// Insert frames a intervals corresponding to 10fps for half the window, then
|
|
// 40fps half the window. The average should be 20fps.
|
|
const double kLowFps = 10.0;
|
|
const double kHighFps = 30.0;
|
|
const double kExpectedFps = 20.0;
|
|
|
|
const Timestamp start_time = clock_.CurrentTime();
|
|
while (clock_.CurrentTime() - start_time < kDefaultWindow / 2) {
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
clock_.AdvanceTime(TimeDelta::seconds(1) / kLowFps);
|
|
}
|
|
while (clock_.CurrentTime() - start_time < kDefaultWindow) {
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
clock_.AdvanceTime(TimeDelta::seconds(1) / kHighFps);
|
|
}
|
|
|
|
EXPECT_NEAR(*estimator_.GetAverageFps(), kExpectedFps, 0.001);
|
|
}
|
|
|
|
TEST_F(FrameRateEstimatorTest, CullsOldFramesFromAveragingWindow) {
|
|
// Two frames, just on the border of the 1s window => 1 fps.
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
clock_.AdvanceTime(kDefaultWindow);
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
EXPECT_TRUE(estimator_.GetAverageFps());
|
|
EXPECT_NEAR(*estimator_.GetAverageFps(), 1.0, 0.001);
|
|
|
|
// Oldest frame should just be pushed out the window, leaving a single frame
|
|
// => no estimate possible.
|
|
clock_.AdvanceTime(TimeDelta::us(1));
|
|
EXPECT_FALSE(estimator_.GetAverageFps(clock_.CurrentTime()));
|
|
}
|
|
|
|
TEST_F(FrameRateEstimatorTest, Reset) {
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
clock_.AdvanceTime(TimeDelta::seconds(1) / 30);
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
EXPECT_TRUE(estimator_.GetAverageFps());
|
|
|
|
// Clear estimator, no estimate should be possible even after inserting one
|
|
// new frame.
|
|
estimator_.Reset();
|
|
EXPECT_FALSE(estimator_.GetAverageFps());
|
|
clock_.AdvanceTime(TimeDelta::seconds(1) / 30);
|
|
estimator_.OnFrame(clock_.CurrentTime());
|
|
EXPECT_FALSE(estimator_.GetAverageFps());
|
|
}
|
|
|
|
} // namespace webrtc
|