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:
RateTrackerForTest()18 RateTrackerForTest() : RateTracker(100u, 10u), time_(0) {}
Time() const19 virtual uint32_t Time() const { return time_; }
AdvanceTime(uint32_t delta)20 void AdvanceTime(uint32_t delta) { time_ += delta; }
21
22 private:
23 uint32_t time_;
24 };
25
TEST(RateTrackerTest,Test30FPS)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
TEST(RateTrackerTest,Test60FPS)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
TEST(RateTrackerTest,TestRateTrackerBasics)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
TEST(RateTrackerTest,TestLongPeriodBetweenSamples)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
TEST(RateTrackerTest,TestRolloff)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
TEST(RateTrackerTest,TestGetUnitSecondsAfterInitialValue)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