frame_rate_estimator_unittest.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/base/frame_rate_estimator.h"
  5. #include <tuple>
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. namespace media {
  8. using FpsPair = std::tuple<int, int>;
  9. class FrameRateEstimatorTest : public testing::TestWithParam<FpsPair> {
  10. public:
  11. void ProvideSamples(base::TimeDelta duration, int count) {
  12. while (count--)
  13. estimator_.AddSample(duration);
  14. }
  15. void ProvideSample(base::TimeDelta duration) {
  16. estimator_.AddSample(duration);
  17. }
  18. int low_fps() const { return std::get<0>(GetParam()); }
  19. int high_fps() const { return std::get<1>(GetParam()); }
  20. base::TimeDelta duration(int fps) { return base::Seconds(1.0 / fps); }
  21. FrameRateEstimator estimator_;
  22. };
  23. TEST_P(FrameRateEstimatorTest, NoEstimateInitially) {
  24. // Asking for an estimate with no samples is okay, though it shouldn't return
  25. // an estimate.
  26. EXPECT_FALSE(estimator_.ComputeFPS());
  27. }
  28. TEST_P(FrameRateEstimatorTest, AverageConvergesThenReset) {
  29. // Verify that the estimate is provided after the required samples are reached
  30. // and that Reset() clears it.
  31. // The initial sample requirement should allow quick convergence.
  32. EXPECT_EQ(estimator_.GetRequiredSamplesForTesting(),
  33. estimator_.GetMinSamplesForTesting());
  34. // Make sure that it doesn't converge before the required sample count.
  35. ProvideSamples(duration(low_fps()),
  36. estimator_.GetRequiredSamplesForTesting() - 1);
  37. EXPECT_FALSE(estimator_.ComputeFPS());
  38. ProvideSample(duration(low_fps()));
  39. EXPECT_EQ(*estimator_.ComputeFPS(), low_fps());
  40. estimator_.Reset();
  41. EXPECT_FALSE(estimator_.ComputeFPS());
  42. ProvideSamples(duration(low_fps()),
  43. estimator_.GetRequiredSamplesForTesting() - 1);
  44. EXPECT_FALSE(estimator_.ComputeFPS());
  45. }
  46. TEST_P(FrameRateEstimatorTest, DurationJitterIsFine) {
  47. // A little jitter doesn't change anything.
  48. ProvideSamples(duration(low_fps()),
  49. estimator_.GetRequiredSamplesForTesting());
  50. // Compute a jitter that's not big enough to move it out of its bucket. We
  51. // use +1 so it works either above or below (below has more room). 2.0 would
  52. // be fine ideally, but we make it a bit smaller than that just to prevent
  53. // floating point weirdness.
  54. auto jitter = (duration(low_fps()) - duration(low_fps() + 1)) / 2.1;
  55. for (int i = 0; i < estimator_.GetRequiredSamplesForTesting(); i++) {
  56. ProvideSample(duration(low_fps()) + jitter);
  57. EXPECT_EQ(*estimator_.ComputeFPS(), low_fps());
  58. }
  59. for (int i = 0; i < estimator_.GetRequiredSamplesForTesting(); i++) {
  60. ProvideSample(duration(low_fps()) - jitter);
  61. EXPECT_EQ(*estimator_.ComputeFPS(), low_fps());
  62. }
  63. }
  64. TEST_P(FrameRateEstimatorTest, AverageDoesntSkew) {
  65. // Changing frame rates shouldn't skew between them. It should stop providing
  66. // estimates temporarily.
  67. ProvideSamples(duration(low_fps()),
  68. estimator_.GetRequiredSamplesForTesting());
  69. EXPECT_EQ(*estimator_.ComputeFPS(), low_fps());
  70. ProvideSample(duration(high_fps()));
  71. EXPECT_FALSE(estimator_.ComputeFPS());
  72. // We should now require more samples one we destabilized.
  73. EXPECT_EQ(estimator_.GetRequiredSamplesForTesting(),
  74. estimator_.GetMaxSamplesForTesting());
  75. ProvideSamples(duration(high_fps()),
  76. estimator_.GetRequiredSamplesForTesting() - 2);
  77. EXPECT_FALSE(estimator_.ComputeFPS());
  78. ProvideSample(duration(high_fps()));
  79. EXPECT_EQ(*estimator_.ComputeFPS(), high_fps());
  80. }
  81. TEST_P(FrameRateEstimatorTest, ResetAllowsFastConvergence) {
  82. // If we're in slow-convergence mode, Reset() should allow fast convergence.
  83. // Get into slow convergence mode by providing a non-uniform window.
  84. ProvideSamples(duration(low_fps()), estimator_.GetMinSamplesForTesting() - 1);
  85. ProvideSamples(duration(high_fps()), 1);
  86. EXPECT_EQ(estimator_.GetRequiredSamplesForTesting(),
  87. estimator_.GetMaxSamplesForTesting());
  88. // See if Reset() gets us back to fast convergence.
  89. estimator_.Reset();
  90. EXPECT_EQ(estimator_.GetRequiredSamplesForTesting(),
  91. estimator_.GetMinSamplesForTesting());
  92. }
  93. // Instantiate tests for lots of common frame rates.
  94. INSTANTIATE_TEST_SUITE_P(All,
  95. FrameRateEstimatorTest,
  96. testing::Values(FpsPair(24, 30),
  97. FpsPair(24, 60),
  98. FpsPair(24, 90),
  99. FpsPair(24, 120),
  100. FpsPair(24, 240),
  101. FpsPair(30, 60),
  102. FpsPair(30, 90),
  103. FpsPair(30, 120),
  104. FpsPair(30, 240),
  105. FpsPair(60, 90),
  106. FpsPair(60, 120),
  107. FpsPair(60, 240),
  108. FpsPair(90, 120),
  109. FpsPair(90, 240),
  110. FpsPair(120, 240)));
  111. } // namespace media