• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdint>
16 
17 namespace webrtc {
18 
FramerateController(float target_framerate_fps)19 FramerateController::FramerateController(float target_framerate_fps)
20     : min_frame_interval_ms_(0), framerate_estimator_(1000.0, 1000.0) {
21   SetTargetRate(target_framerate_fps);
22 }
23 
SetTargetRate(float target_framerate_fps)24 void 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 
GetTargetRate()37 float FramerateController::GetTargetRate() {
38   return *target_framerate_fps_;
39 }
40 
Reset()41 void FramerateController::Reset() {
42   framerate_estimator_.Reset();
43   last_timestamp_ms_.reset();
44 }
45 
DropFrame(uint32_t timestamp_ms) const46 bool 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 
AddFrame(uint32_t timestamp_ms)69 void 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 
Rate(uint32_t timestamp_ms) const79 absl::optional<float> FramerateController::Rate(uint32_t timestamp_ms) const {
80   return framerate_estimator_.Rate(timestamp_ms);
81 }
82 
83 }  // namespace webrtc
84