blob: ce8ab127124a628643fd8091c47bfea479769353 [file] [log] [blame]
Sergey Silkinae3144c2018-08-29 01:05:26 +02001/*
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 "rtc_base/checks.h"
14
15namespace webrtc {
16
17FramerateController::FramerateController(float target_framerate_fps)
18 : min_frame_interval_ms_(0), framerate_estimator_(1000.0, 1000.0) {
19 SetTargetRate(target_framerate_fps);
20}
21
22void FramerateController::SetTargetRate(float target_framerate_fps) {
23 if (target_framerate_fps_ != target_framerate_fps) {
24 framerate_estimator_.Reset();
25 if (last_timestamp_ms_) {
26 framerate_estimator_.Update(1, *last_timestamp_ms_);
27 }
28
29 const size_t target_frame_interval_ms = 1000 / target_framerate_fps;
30 target_framerate_fps_ = target_framerate_fps;
31 min_frame_interval_ms_ = 85 * target_frame_interval_ms / 100;
32 }
33}
34
35float FramerateController::GetTargetRate() {
36 return *target_framerate_fps_;
37}
38
39void FramerateController::Reset() {
40 framerate_estimator_.Reset();
41 last_timestamp_ms_.reset();
42}
43
44bool FramerateController::DropFrame(uint32_t timestamp_ms) const {
45 if (timestamp_ms < last_timestamp_ms_) {
46 // Timestamp jumps backward. We can't make adequate drop decision. Don't
47 // drop this frame. Stats will be reset in AddFrame().
48 return false;
49 }
50
51 if (Rate(timestamp_ms).value_or(*target_framerate_fps_) >
52 target_framerate_fps_) {
53 return true;
54 }
55
56 if (last_timestamp_ms_) {
57 const int64_t diff_ms =
58 static_cast<int64_t>(timestamp_ms) - *last_timestamp_ms_;
59 if (diff_ms < min_frame_interval_ms_) {
60 return true;
61 }
62 }
63
64 return false;
65}
66
67void FramerateController::AddFrame(uint32_t timestamp_ms) {
68 if (timestamp_ms < last_timestamp_ms_) {
69 // Timestamp jumps backward.
70 Reset();
71 }
72
73 framerate_estimator_.Update(1, timestamp_ms);
74 last_timestamp_ms_ = timestamp_ms;
75}
76
77absl::optional<float> FramerateController::Rate(uint32_t timestamp_ms) const {
78 return framerate_estimator_.Rate(timestamp_ms);
79}
80
81} // namespace webrtc