18fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org/* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 28fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org * 38fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org * Use of this source code is governed by a BSD-style license 48fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org * that can be found in the LICENSE file in the root of the source 58fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org * tree. An additional intellectual property rights grant can be found 68fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org * in the file PATENTS. All contributing project authors may 78fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org * be found in the AUTHORS file in the root of the source tree. 88fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org */ 98fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 108fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org#include "webrtc/modules/video_coding/main/source/jitter_estimator.h" 118fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 128fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 138fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org#include "webrtc/system_wrappers/interface/clock.h" 148fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 158fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgnamespace webrtc { 168fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 178fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgclass TestEstimator : public VCMJitterEstimator { 188fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org public: 198fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org explicit TestEstimator(bool exp_enabled) 208fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org : VCMJitterEstimator(&fake_clock_, 0, 0), 218fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org fake_clock_(0), 228fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org exp_enabled_(exp_enabled) {} 238fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 248fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org virtual bool LowRateExperimentEnabled() { return exp_enabled_; } 258fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 268fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org void AdvanceClock(int64_t microseconds) { 278fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org fake_clock_.AdvanceTimeMicroseconds(microseconds); 288fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 298fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 308fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org private: 318fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org SimulatedClock fake_clock_; 328fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org const bool exp_enabled_; 338fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org}; 348fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 358fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgclass TestVCMJitterEstimator : public ::testing::Test { 368fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org protected: 378fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org TestVCMJitterEstimator() 388fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org : regular_estimator_(false), low_rate_estimator_(true) {} 398fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 408fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org virtual void SetUp() { regular_estimator_.Reset(); } 418fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 428fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org TestEstimator regular_estimator_; 438fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org TestEstimator low_rate_estimator_; 448fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org}; 458fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 468fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org// Generates some simple test data in the form of a sawtooth wave. 478fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgclass ValueGenerator { 488fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org public: 498fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org ValueGenerator(int32_t amplitude) : amplitude_(amplitude), counter_(0) {} 508fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org virtual ~ValueGenerator() {} 518fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 528fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org int64_t Delay() { return ((counter_ % 11) - 5) * amplitude_; } 538fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 548fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org uint32_t FrameSize() { return 1000 + Delay(); } 558fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 568fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org void Advance() { ++counter_; } 578fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 588fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org private: 598fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org const int32_t amplitude_; 608fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org int64_t counter_; 618fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org}; 628fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 638fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org// 5 fps, disable jitter delay altogether. 648fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgTEST_F(TestVCMJitterEstimator, TestLowRate) { 658fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org ValueGenerator gen(10); 668fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org uint64_t time_delta = 1000000 / 5; 678fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org for (int i = 0; i < 60; ++i) { 688fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 698fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.AdvanceClock(time_delta); 708fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 718fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.AdvanceClock(time_delta); 728fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_GT(regular_estimator_.GetJitterEstimate(0), 0); 738fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org if (i > 2) 748fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_EQ(low_rate_estimator_.GetJitterEstimate(0), 0); 758fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org gen.Advance(); 768fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 778fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org} 788fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 798fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org// 8 fps, steady state estimate should be in interpolated interval between 0 808fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org// and value of previous method. 818fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgTEST_F(TestVCMJitterEstimator, TestMidRate) { 828fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org ValueGenerator gen(10); 838fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org uint64_t time_delta = 1000000 / 8; 848fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org for (int i = 0; i < 60; ++i) { 858fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 868fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.AdvanceClock(time_delta); 878fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 888fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.AdvanceClock(time_delta); 898fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_GT(regular_estimator_.GetJitterEstimate(0), 0); 908fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_GT(low_rate_estimator_.GetJitterEstimate(0), 0); 918fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_GE(regular_estimator_.GetJitterEstimate(0), 928fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.GetJitterEstimate(0)); 938fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org gen.Advance(); 948fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 958fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org} 968fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 978fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org// 30 fps, steady state estimate should be same as previous method. 988fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgTEST_F(TestVCMJitterEstimator, TestHighRate) { 998fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org ValueGenerator gen(10); 1008fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org uint64_t time_delta = 1000000 / 30; 1018fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org for (int i = 0; i < 60; ++i) { 1028fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 1038fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.AdvanceClock(time_delta); 1048fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 1058fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.AdvanceClock(time_delta); 1068fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_EQ(regular_estimator_.GetJitterEstimate(0), 1078fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.GetJitterEstimate(0)); 1088fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org gen.Advance(); 1098fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1108fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org} 1118fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 1128fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org// 10 fps, high jitter then low jitter. Low rate estimator should converge 1138fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org// faster to low noise estimate. 1148fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgTEST_F(TestVCMJitterEstimator, TestConvergence) { 1158fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org // Reach a steady state with high noise. 1168fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org ValueGenerator gen(50); 1178fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org uint64_t time_delta = 1000000 / 10; 1188fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org for (int i = 0; i < 100; ++i) { 1198fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 1208fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.AdvanceClock(time_delta * 2); 1218fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); 1228fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.AdvanceClock(time_delta * 2); 1238fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org gen.Advance(); 1248fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1258fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 1268fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org int threshold = regular_estimator_.GetJitterEstimate(0) / 2; 1278fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 1288fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org // New generator with zero noise. 1298fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org ValueGenerator low_gen(0); 1308fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org int regular_iterations = 0; 1318fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org int low_rate_iterations = 0; 1328fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org for (int i = 0; i < 500; ++i) { 1338fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org if (regular_iterations == 0) { 1348fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.UpdateEstimate(low_gen.Delay(), low_gen.FrameSize()); 1358fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_estimator_.AdvanceClock(time_delta); 1368fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org if (regular_estimator_.GetJitterEstimate(0) < threshold) { 1378fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org regular_iterations = i; 1388fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1398fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1408fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 1418fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org if (low_rate_iterations == 0) { 1428fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.UpdateEstimate(low_gen.Delay(), low_gen.FrameSize()); 1438fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_estimator_.AdvanceClock(time_delta); 1448fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org if (low_rate_estimator_.GetJitterEstimate(0) < threshold) { 1458fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org low_rate_iterations = i; 1468fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1478fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1488fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 1498fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org if (regular_iterations != 0 && low_rate_iterations != 0) { 1508fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org break; 1518fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1528fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 1538fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org gen.Advance(); 1548fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org } 1558fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org 1568fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_NE(regular_iterations, 0); 1578fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_NE(low_rate_iterations, 0); 1588fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org EXPECT_LE(low_rate_iterations, regular_iterations); 1598fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org} 1608fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org} 161