1 /*
2  *  Copyright (c) 2018 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 "modules/video_coding/utility/framerate_controller.h"
12 
13 #include <stddef.h>
14 
15 #include "test/gtest.h"
16 
17 namespace webrtc {
18 
TEST(FramerateController,KeepTargetFramerate)19 TEST(FramerateController, KeepTargetFramerate) {
20   const float input_framerate_fps = 20;
21   const float target_framerate_fps = 5;
22   const float max_abs_framerate_error_fps = target_framerate_fps * 0.1f;
23   const size_t input_duration_secs = 3;
24   const size_t num_input_frames = input_duration_secs * input_framerate_fps;
25 
26   FramerateController framerate_controller(target_framerate_fps);
27   size_t num_dropped_frames = 0;
28   for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
29     const uint32_t timestamp_ms =
30         static_cast<uint32_t>(1000 * frame_num / input_framerate_fps);
31     if (framerate_controller.DropFrame(timestamp_ms)) {
32       ++num_dropped_frames;
33     } else {
34       framerate_controller.AddFrame(timestamp_ms);
35     }
36   }
37 
38   const float output_framerate_fps =
39       static_cast<float>(num_input_frames - num_dropped_frames) /
40       input_duration_secs;
41   EXPECT_NEAR(output_framerate_fps, target_framerate_fps,
42               max_abs_framerate_error_fps);
43 }
44 
TEST(FramerateController,DoNotDropAnyFramesIfTargerEqualsInput)45 TEST(FramerateController, DoNotDropAnyFramesIfTargerEqualsInput) {
46   const float input_framerate_fps = 30;
47   const size_t input_duration_secs = 3;
48   const size_t num_input_frames = input_duration_secs * input_framerate_fps;
49 
50   FramerateController framerate_controller(input_framerate_fps);
51   size_t num_dropped_frames = 0;
52   for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
53     const uint32_t timestamp_ms =
54         static_cast<uint32_t>(1000 * frame_num / input_framerate_fps);
55     if (framerate_controller.DropFrame(timestamp_ms)) {
56       ++num_dropped_frames;
57     } else {
58       framerate_controller.AddFrame(timestamp_ms);
59     }
60   }
61 
62   EXPECT_EQ(num_dropped_frames, 0U);
63 }
64 
TEST(FramerateController,DoNotDropFrameWhenTimestampJumpsBackward)65 TEST(FramerateController, DoNotDropFrameWhenTimestampJumpsBackward) {
66   FramerateController framerate_controller(30);
67   ASSERT_FALSE(framerate_controller.DropFrame(66));
68   framerate_controller.AddFrame(66);
69   EXPECT_FALSE(framerate_controller.DropFrame(33));
70 }
71 
TEST(FramerateController,DropFrameIfItIsTooCloseToPreviousFrame)72 TEST(FramerateController, DropFrameIfItIsTooCloseToPreviousFrame) {
73   FramerateController framerate_controller(30);
74   ASSERT_FALSE(framerate_controller.DropFrame(33));
75   framerate_controller.AddFrame(33);
76   EXPECT_TRUE(framerate_controller.DropFrame(34));
77 }
78 
TEST(FramerateController,FrameDroppingStartsFromSecondInputFrame)79 TEST(FramerateController, FrameDroppingStartsFromSecondInputFrame) {
80   const float input_framerate_fps = 23;
81   const float target_framerate_fps = 19;
82   const uint32_t input_frame_duration_ms =
83       static_cast<uint32_t>(1000 / input_framerate_fps);
84   FramerateController framerate_controller(target_framerate_fps);
85   ASSERT_FALSE(framerate_controller.DropFrame(1 * input_frame_duration_ms));
86   framerate_controller.AddFrame(1 * input_frame_duration_ms);
87   EXPECT_TRUE(framerate_controller.DropFrame(2 * input_frame_duration_ms));
88 }
89 
90 }  // namespace webrtc
91