framerate_controller_unittest.cc (5545B)
1 /* 2 * Copyright 2021 The WebRTC Project Authors. All rights reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "common_video/framerate_controller.h" 12 13 #include <cstdint> 14 15 #include "rtc_base/time_utils.h" 16 #include "test/gtest.h" 17 18 namespace webrtc { 19 namespace { 20 constexpr int kInputFps = 30; 21 constexpr int kNumFrames = 60; 22 } // namespace 23 24 class FramerateControllerTest : public ::testing::Test { 25 protected: 26 int64_t GetNextTimestampNs() { 27 int64_t interval_us = kNumMicrosecsPerSec / kInputFps; 28 next_timestamp_us_ += interval_us; 29 return next_timestamp_us_ * kNumNanosecsPerMicrosec; 30 } 31 32 int64_t next_timestamp_us_ = TimeMicros(); 33 FramerateController controller_; 34 }; 35 36 TEST_F(FramerateControllerTest, NoFramesDroppedIfNothingRequested) { 37 // Default max framerate is maxdouble. 38 for (int i = 1; i < kNumFrames; ++i) 39 EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs())); 40 } 41 42 TEST_F(FramerateControllerTest, AllFramesDroppedIfZeroRequested) { 43 controller_.SetMaxFramerate(0); 44 45 for (int i = 1; i < kNumFrames; ++i) 46 EXPECT_TRUE(controller_.ShouldDropFrame(GetNextTimestampNs())); 47 } 48 49 TEST_F(FramerateControllerTest, AllFramesDroppedIfNegativeRequested) { 50 controller_.SetMaxFramerate(-1); 51 52 for (int i = 1; i < kNumFrames; ++i) 53 EXPECT_TRUE(controller_.ShouldDropFrame(GetNextTimestampNs())); 54 } 55 56 TEST_F(FramerateControllerTest, EverySecondFrameDroppedIfHalfRequested) { 57 controller_.SetMaxFramerate(kInputFps / 2); 58 59 // The first frame should not be dropped. 60 for (int i = 1; i < kNumFrames; ++i) 61 EXPECT_EQ(i % 2 == 0, controller_.ShouldDropFrame(GetNextTimestampNs())); 62 } 63 64 TEST_F(FramerateControllerTest, EveryThirdFrameDroppedIfTwoThirdsRequested) { 65 controller_.SetMaxFramerate(kInputFps * 2 / 3); 66 67 // The first frame should not be dropped. 68 for (int i = 1; i < kNumFrames; ++i) 69 EXPECT_EQ(i % 3 == 0, controller_.ShouldDropFrame(GetNextTimestampNs())); 70 } 71 72 TEST_F(FramerateControllerTest, NoFrameDroppedIfTwiceRequested) { 73 controller_.SetMaxFramerate(kInputFps * 2); 74 75 for (int i = 1; i < kNumFrames; ++i) 76 EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs())); 77 } 78 79 TEST_F(FramerateControllerTest, TestAverageFramerate) { 80 const double kMaxFps = 18.2; 81 controller_.SetMaxFramerate(kMaxFps); 82 83 const int kNumSec = 10; 84 int frames_kept = 0; 85 for (int i = 0; i < kInputFps * kNumSec; ++i) { 86 if (!controller_.ShouldDropFrame(GetNextTimestampNs())) 87 ++frames_kept; 88 } 89 double average_fps = static_cast<double>(frames_kept) / kNumSec; 90 EXPECT_NEAR(kMaxFps, average_fps, 0.01); 91 } 92 93 TEST_F(FramerateControllerTest, NoFrameDroppedForLargeTimestampOffset) { 94 controller_.SetMaxFramerate(kInputFps); 95 EXPECT_FALSE(controller_.ShouldDropFrame(0)); 96 97 const int64_t kLargeOffsetNs = -987654321LL * 1000; 98 EXPECT_FALSE(controller_.ShouldDropFrame(kLargeOffsetNs)); 99 100 int64_t input_interval_ns = kNumNanosecsPerSec / kInputFps; 101 EXPECT_FALSE(controller_.ShouldDropFrame(kLargeOffsetNs + input_interval_ns)); 102 } 103 104 TEST_F(FramerateControllerTest, NoFrameDroppedIfInputWithJitterRequested) { 105 controller_.SetMaxFramerate(kInputFps); 106 107 // Input fps with jitter. 108 int64_t input_interval_ns = kNumNanosecsPerSec / kInputFps; 109 EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 0 / 10)); 110 EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 10 / 10 - 1)); 111 EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 25 / 10)); 112 EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 30 / 10)); 113 EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 35 / 10)); 114 EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 50 / 10)); 115 } 116 117 TEST_F(FramerateControllerTest, FrameDroppedWhenReductionRequested) { 118 controller_.SetMaxFramerate(kInputFps); 119 120 // Expect no frame drop. 121 for (int i = 1; i < kNumFrames; ++i) 122 EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs())); 123 124 // Reduce max frame rate. 125 controller_.SetMaxFramerate(kInputFps / 2); 126 127 // Verify that every other frame is dropped. 128 for (int i = 1; i < kNumFrames; ++i) 129 EXPECT_EQ(i % 2 == 0, controller_.ShouldDropFrame(GetNextTimestampNs())); 130 } 131 132 TEST_F(FramerateControllerTest, NoFramesDroppedAfterReset) { 133 controller_.SetMaxFramerate(0); 134 135 // All frames dropped. 136 for (int i = 1; i < kNumFrames; ++i) 137 EXPECT_TRUE(controller_.ShouldDropFrame(GetNextTimestampNs())); 138 139 controller_.Reset(); 140 141 // Expect no frame drop after reset. 142 for (int i = 1; i < kNumFrames; ++i) 143 EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs())); 144 } 145 146 TEST_F(FramerateControllerTest, TestKeepFrame) { 147 FramerateController controller(kInputFps / 2); 148 149 EXPECT_FALSE(controller.ShouldDropFrame(GetNextTimestampNs())); 150 EXPECT_TRUE(controller.ShouldDropFrame(GetNextTimestampNs())); 151 EXPECT_FALSE(controller.ShouldDropFrame(GetNextTimestampNs())); 152 EXPECT_TRUE(controller.ShouldDropFrame(GetNextTimestampNs())); 153 EXPECT_FALSE(controller.ShouldDropFrame(GetNextTimestampNs())); 154 155 // Next frame should be dropped. 156 // Keep this frame (e.g. in case of a key frame). 157 controller.KeepFrame(GetNextTimestampNs()); 158 // Expect next frame to be dropped instead. 159 EXPECT_TRUE(controller.ShouldDropFrame(GetNextTimestampNs())); 160 } 161 162 } // namespace webrtc