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