1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/*
26304626268238a074051910d201e9a77aae677e0Tim Psiaki *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *
4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */
10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/gunit.h"
12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/ratetracker.h"
13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc {
15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass RateTrackerForTest : public RateTracker {
17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
186304626268238a074051910d201e9a77aae677e0Tim Psiaki  RateTrackerForTest() : RateTracker(100u, 10u), time_(0) {}
190c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  virtual uint32_t Time() const { return time_; }
200c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  void AdvanceTime(uint32_t delta) { time_ += delta; }
21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
230c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t time_;
24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
266304626268238a074051910d201e9a77aae677e0Tim PsiakiTEST(RateTrackerTest, Test30FPS) {
27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  RateTrackerForTest tracker;
286304626268238a074051910d201e9a77aae677e0Tim Psiaki
296304626268238a074051910d201e9a77aae677e0Tim Psiaki  for (int i = 0; i < 300; ++i) {
306304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AddSamples(1);
316304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AdvanceTime(33);
326304626268238a074051910d201e9a77aae677e0Tim Psiaki    if (i % 3 == 0) {
336304626268238a074051910d201e9a77aae677e0Tim Psiaki      tracker.AdvanceTime(1);
346304626268238a074051910d201e9a77aae677e0Tim Psiaki    }
356304626268238a074051910d201e9a77aae677e0Tim Psiaki  }
366304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(30.0, tracker.ComputeRateForInterval(50000u));
376304626268238a074051910d201e9a77aae677e0Tim Psiaki}
386304626268238a074051910d201e9a77aae677e0Tim Psiaki
396304626268238a074051910d201e9a77aae677e0Tim PsiakiTEST(RateTrackerTest, Test60FPS) {
406304626268238a074051910d201e9a77aae677e0Tim Psiaki  RateTrackerForTest tracker;
416304626268238a074051910d201e9a77aae677e0Tim Psiaki
426304626268238a074051910d201e9a77aae677e0Tim Psiaki  for (int i = 0; i < 300; ++i) {
436304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AddSamples(1);
446304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AdvanceTime(16);
456304626268238a074051910d201e9a77aae677e0Tim Psiaki    if (i % 3 != 0) {
466304626268238a074051910d201e9a77aae677e0Tim Psiaki      tracker.AdvanceTime(1);
476304626268238a074051910d201e9a77aae677e0Tim Psiaki    }
486304626268238a074051910d201e9a77aae677e0Tim Psiaki  }
496304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(60.0, tracker.ComputeRateForInterval(1000u));
506304626268238a074051910d201e9a77aae677e0Tim Psiaki}
516304626268238a074051910d201e9a77aae677e0Tim Psiaki
526304626268238a074051910d201e9a77aae677e0Tim PsiakiTEST(RateTrackerTest, TestRateTrackerBasics) {
536304626268238a074051910d201e9a77aae677e0Tim Psiaki  RateTrackerForTest tracker;
546304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRateForInterval(1000u));
55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Add a sample.
576304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AddSamples(1234);
58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Advance the clock by 100 ms.
59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  tracker.AdvanceTime(100);
606304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRateForInterval(1000u));
616304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRate());
626304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_EQ(1234U, tracker.TotalSampleCount());
636304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeTotalRate());
64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Repeat.
666304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AddSamples(1234);
67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  tracker.AdvanceTime(100);
686304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRateForInterval(1000u));
696304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeRate());
706304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_EQ(1234U * 2, tracker.TotalSampleCount());
716304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(12340.0, tracker.ComputeTotalRate());
72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Advance the clock by 800 ms, so we've elapsed a full second.
74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // units_second should now be filled in properly.
75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  tracker.AdvanceTime(800);
766304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRateForInterval(1000u));
776304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRate());
786304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_EQ(1234U * 2, tracker.TotalSampleCount());
796304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeTotalRate());
80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Poll the tracker again immediately. The reported rate should stay the same.
826304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRateForInterval(1000u));
836304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeRate());
846304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_EQ(1234U * 2, tracker.TotalSampleCount());
856304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0 * 2.0, tracker.ComputeTotalRate());
86f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Do nothing and advance by a second. We should drop down to zero.
88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  tracker.AdvanceTime(1000);
896304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRateForInterval(1000u));
906304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRate());
916304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_EQ(1234U * 2, tracker.TotalSampleCount());
926304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0, tracker.ComputeTotalRate());
93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Send a bunch of data at a constant rate for 5.5 "seconds".
95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // We should report the rate properly.
96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (int i = 0; i < 5500; i += 100) {
976304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AddSamples(9876U);
98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    tracker.AdvanceTime(100);
99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1006304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(9876.0 * 10.0, tracker.ComputeRateForInterval(1000u));
1016304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(9876.0 * 10.0, tracker.ComputeRate());
1026304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_EQ(1234U * 2 + 9876U * 55, tracker.TotalSampleCount());
1036304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ((1234.0 * 2.0 + 9876.0 * 55.0) / 7.5,
1046304626268238a074051910d201e9a77aae677e0Tim Psiaki      tracker.ComputeTotalRate());
105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Advance the clock by 500 ms. Since we sent nothing over this half-second,
107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // the reported rate should be reduced by half.
108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  tracker.AdvanceTime(500);
1096304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(9876.0 * 5.0, tracker.ComputeRateForInterval(1000u));
1106304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(9876.0 * 5.0, tracker.ComputeRate());
1116304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_EQ(1234U * 2 + 9876U * 55, tracker.TotalSampleCount());
1126304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ((1234.0 * 2.0 + 9876.0 * 55.0) / 8.0,
1136304626268238a074051910d201e9a77aae677e0Tim Psiaki      tracker.ComputeTotalRate());
1146304626268238a074051910d201e9a77aae677e0Tim Psiaki
1156304626268238a074051910d201e9a77aae677e0Tim Psiaki  // Rate over the last half second should be zero.
1166304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRateForInterval(500u));
1176304626268238a074051910d201e9a77aae677e0Tim Psiaki}
1186304626268238a074051910d201e9a77aae677e0Tim Psiaki
1196304626268238a074051910d201e9a77aae677e0Tim PsiakiTEST(RateTrackerTest, TestLongPeriodBetweenSamples) {
1206304626268238a074051910d201e9a77aae677e0Tim Psiaki  RateTrackerForTest tracker;
1216304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AddSamples(1);
1226304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AdvanceTime(1000);
1236304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1.0, tracker.ComputeRate());
1246304626268238a074051910d201e9a77aae677e0Tim Psiaki
1256304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AdvanceTime(2000);
1266304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(0.0, tracker.ComputeRate());
1276304626268238a074051910d201e9a77aae677e0Tim Psiaki
1286304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AdvanceTime(2000);
1296304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AddSamples(1);
1306304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1.0, tracker.ComputeRate());
1316304626268238a074051910d201e9a77aae677e0Tim Psiaki}
1326304626268238a074051910d201e9a77aae677e0Tim Psiaki
1336304626268238a074051910d201e9a77aae677e0Tim PsiakiTEST(RateTrackerTest, TestRolloff) {
1346304626268238a074051910d201e9a77aae677e0Tim Psiaki  RateTrackerForTest tracker;
1356304626268238a074051910d201e9a77aae677e0Tim Psiaki  for (int i = 0; i < 10; ++i) {
1366304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AddSamples(1U);
1376304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AdvanceTime(100);
1386304626268238a074051910d201e9a77aae677e0Tim Psiaki  }
1396304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(10.0, tracker.ComputeRate());
1406304626268238a074051910d201e9a77aae677e0Tim Psiaki
1416304626268238a074051910d201e9a77aae677e0Tim Psiaki  for (int i = 0; i < 10; ++i) {
1426304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AddSamples(1U);
1436304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AdvanceTime(50);
1446304626268238a074051910d201e9a77aae677e0Tim Psiaki  }
1456304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(15.0, tracker.ComputeRate());
1466304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(20.0, tracker.ComputeRateForInterval(500u));
1476304626268238a074051910d201e9a77aae677e0Tim Psiaki
1486304626268238a074051910d201e9a77aae677e0Tim Psiaki  for (int i = 0; i < 10; ++i) {
1496304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AddSamples(1U);
1506304626268238a074051910d201e9a77aae677e0Tim Psiaki    tracker.AdvanceTime(50);
1516304626268238a074051910d201e9a77aae677e0Tim Psiaki  }
1526304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(20.0, tracker.ComputeRate());
153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
155a78a94e838467260f80b08b83b1b5b92564d6c91perkj@webrtc.orgTEST(RateTrackerTest, TestGetUnitSecondsAfterInitialValue) {
156a78a94e838467260f80b08b83b1b5b92564d6c91perkj@webrtc.org  RateTrackerForTest tracker;
1576304626268238a074051910d201e9a77aae677e0Tim Psiaki  tracker.AddSamples(1234);
158a78a94e838467260f80b08b83b1b5b92564d6c91perkj@webrtc.org  tracker.AdvanceTime(1000);
1596304626268238a074051910d201e9a77aae677e0Tim Psiaki  EXPECT_DOUBLE_EQ(1234.0, tracker.ComputeRateForInterval(1000u));
160a78a94e838467260f80b08b83b1b5b92564d6c91perkj@webrtc.org}
161a78a94e838467260f80b08b83b1b5b92564d6c91perkj@webrtc.org
162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace rtc
163