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