1 /* 2 * Copyright 2015 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 "webrtc/base/gunit.h" 12 #include "webrtc/base/ratetracker.h" 13 14 namespace rtc { 15 16 class RateTrackerForTest : public RateTracker { 17 public: 18 RateTrackerForTest() : RateTracker(100u, 10u), time_(0) {} 19 virtual uint32_t Time() const { return time_; } 20 void AdvanceTime(uint32_t delta) { time_ += delta; } 21 22 private: 23 uint32_t time_; 24 }; 25 26 TEST(RateTrackerTest, Test30FPS) { 27 RateTrackerForTest tracker; 28 29 for (int i = 0; i < 300; ++i) { 30 tracker.AddSamples(1); 31 tracker.AdvanceTime(33); 32 if (i % 3 == 0) { 33 tracker.AdvanceTime(1); 34 } 35 } 36 EXPECT_DOUBLE_EQ(30.0, tracker.ComputeRateForInterval(50000u)); 37 } 38 39 TEST(RateTrackerTest, Test60FPS) { 40 RateTrackerForTest tracker; 41 42 for (int i = 0; i < 300; ++i) { 43 tracker.AddSamples(1); 44 tracker.AdvanceTime(16); 45 if (i % 3 != 0) { 46 tracker.AdvanceTime(1); 47 } 48 } 49 EXPECT_DOUBLE_EQ(60.0, tracker.ComputeRateForInterval(1000u)); 50 } 51 52 TEST(RateTrackerTest, TestRateTrackerBasics) { 53 RateTrackerForTest tracker; 54 EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRateForInterval(1000u)); 55 56 // Add a sample. 57 tracker.AddSamples(1234); 58 // Advance the clock by 100 ms. 59 tracker.AdvanceTime(100); 60 EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRateForInterval(1000u)); 61 EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRate()); 62 EXPECT_EQ(1234U, tracker.TotalSampleCount()); 63 EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeTotalRate()); 64 65 // Repeat. 66 tracker.AddSamples(1234); 67 tracker.AdvanceTime(100); 68 EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRateForInterval(1000u)); 69 EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRate()); 70 EXPECT_EQ(1234U * 2, tracker.TotalSampleCount()); 71 EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeTotalRate()); 72 73 // Advance the clock by 800 ms, so we've elapsed a full second. 74 // units_second should now be filled in properly. 75 tracker.AdvanceTime(800); 76 EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRateForInterval(1000u)); 77 EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRate()); 78 EXPECT_EQ(1234U * 2, tracker.TotalSampleCount()); 79 EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeTotalRate()); 80 81 // Poll the tracker again immediately. The reported rate should stay the same. 82 EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRateForInterval(1000u)); 83 EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRate()); 84 EXPECT_EQ(1234U * 2, tracker.TotalSampleCount()); 85 EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeTotalRate()); 86 87 // Do nothing and advance by a second. We should drop down to zero. 88 tracker.AdvanceTime(1000); 89 EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRateForInterval(1000u)); 90 EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRate()); 91 EXPECT_EQ(1234U * 2, tracker.TotalSampleCount()); 92 EXPECT_DOUBLE_EQ(1234.0, tracker.ComputeTotalRate()); 93 94 // Send a bunch of data at a constant rate for 5.5 "seconds". 95 // We should report the rate properly. 96 for (int i = 0; i < 5500; i += 100) { 97 tracker.AddSamples(9876U); 98 tracker.AdvanceTime(100); 99 } 100 EXPECT_DOUBLE_EQ(9876.0 * 10.0, tracker.ComputeRateForInterval(1000u)); 101 EXPECT_DOUBLE_EQ(9876.0 * 10.0, tracker.ComputeRate()); 102 EXPECT_EQ(1234U * 2 + 9876U * 55, tracker.TotalSampleCount()); 103 EXPECT_DOUBLE_EQ((1234.0 * 2.0 + 9876.0 * 55.0) / 7.5, 104 tracker.ComputeTotalRate()); 105 106 // Advance the clock by 500 ms. Since we sent nothing over this half-second, 107 // the reported rate should be reduced by half. 108 tracker.AdvanceTime(500); 109 EXPECT_DOUBLE_EQ(9876.0 * 5.0, tracker.ComputeRateForInterval(1000u)); 110 EXPECT_DOUBLE_EQ(9876.0 * 5.0, tracker.ComputeRate()); 111 EXPECT_EQ(1234U * 2 + 9876U * 55, tracker.TotalSampleCount()); 112 EXPECT_DOUBLE_EQ((1234.0 * 2.0 + 9876.0 * 55.0) / 8.0, 113 tracker.ComputeTotalRate()); 114 115 // Rate over the last half second should be zero. 116 EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRateForInterval(500u)); 117 } 118 119 TEST(RateTrackerTest, TestLongPeriodBetweenSamples) { 120 RateTrackerForTest tracker; 121 tracker.AddSamples(1); 122 tracker.AdvanceTime(1000); 123 EXPECT_DOUBLE_EQ(1.0, tracker.ComputeRate()); 124 125 tracker.AdvanceTime(2000); 126 EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRate()); 127 128 tracker.AdvanceTime(2000); 129 tracker.AddSamples(1); 130 EXPECT_DOUBLE_EQ(1.0, tracker.ComputeRate()); 131 } 132 133 TEST(RateTrackerTest, TestRolloff) { 134 RateTrackerForTest tracker; 135 for (int i = 0; i < 10; ++i) { 136 tracker.AddSamples(1U); 137 tracker.AdvanceTime(100); 138 } 139 EXPECT_DOUBLE_EQ(10.0, tracker.ComputeRate()); 140 141 for (int i = 0; i < 10; ++i) { 142 tracker.AddSamples(1U); 143 tracker.AdvanceTime(50); 144 } 145 EXPECT_DOUBLE_EQ(15.0, tracker.ComputeRate()); 146 EXPECT_DOUBLE_EQ(20.0, tracker.ComputeRateForInterval(500u)); 147 148 for (int i = 0; i < 10; ++i) { 149 tracker.AddSamples(1U); 150 tracker.AdvanceTime(50); 151 } 152 EXPECT_DOUBLE_EQ(20.0, tracker.ComputeRate()); 153 } 154 155 TEST(RateTrackerTest, TestGetUnitSecondsAfterInitialValue) { 156 RateTrackerForTest tracker; 157 tracker.AddSamples(1234); 158 tracker.AdvanceTime(1000); 159 EXPECT_DOUBLE_EQ(1234.0, tracker.ComputeRateForInterval(1000u)); 160 } 161 162 } // namespace rtc 163