1 /*
2  *  Copyright (c) 2019 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 #ifndef VIDEO_ENCODER_OVERSHOOT_DETECTOR_H_
12 #define VIDEO_ENCODER_OVERSHOOT_DETECTOR_H_
13 
14 #include <deque>
15 
16 #include "absl/types/optional.h"
17 #include "api/units/data_rate.h"
18 
19 namespace webrtc {
20 
21 class EncoderOvershootDetector {
22  public:
23   explicit EncoderOvershootDetector(int64_t window_size_ms);
24   ~EncoderOvershootDetector();
25 
26   void SetTargetRate(DataRate target_bitrate,
27                      double target_framerate_fps,
28                      int64_t time_ms);
29   // A frame has been encoded or dropped. |bytes| == 0 indicates a drop.
30   void OnEncodedFrame(size_t bytes, int64_t time_ms);
31   // This utilization factor reaches 1.0 only if the encoder produces encoded
32   // frame in such a way that they can be sent onto the network at
33   // |target_bitrate| without building growing queues.
34   absl::optional<double> GetNetworkRateUtilizationFactor(int64_t time_ms);
35   // This utilization factor is based just on actual encoded frame sizes in
36   // relation to ideal sizes. An undershoot may be compensated by an
37   // overshoot so that the average over time is close to |target_bitrate|.
38   absl::optional<double> GetMediaRateUtilizationFactor(int64_t time_ms);
39   void Reset();
40 
41  private:
42   int64_t IdealFrameSizeBits() const;
43   void LeakBits(int64_t time_ms);
44   void CullOldUpdates(int64_t time_ms);
45   // Updates provided buffer and checks if overuse ensues, returns
46   // the calculated utilization factor for this frame.
47   double HandleEncodedFrame(size_t frame_size_bits,
48                             int64_t ideal_frame_size_bits,
49                             int64_t time_ms,
50                             int64_t* buffer_level_bits) const;
51 
52   const int64_t window_size_ms_;
53   int64_t time_last_update_ms_;
54   struct BitrateUpdate {
BitrateUpdateBitrateUpdate55     BitrateUpdate(double network_utilization_factor,
56                   double media_utilization_factor,
57                   int64_t update_time_ms)
58         : network_utilization_factor(network_utilization_factor),
59           media_utilization_factor(media_utilization_factor),
60           update_time_ms(update_time_ms) {}
61     // The utilization factor based on strict network rate.
62     double network_utilization_factor;
63     // The utilization based on average media rate.
64     double media_utilization_factor;
65     int64_t update_time_ms;
66   };
67   std::deque<BitrateUpdate> utilization_factors_;
68   double sum_network_utilization_factors_;
69   double sum_media_utilization_factors_;
70   DataRate target_bitrate_;
71   double target_framerate_fps_;
72   int64_t network_buffer_level_bits_;
73   int64_t media_buffer_level_bits_;
74 };
75 
76 }  // namespace webrtc
77 
78 #endif  // VIDEO_ENCODER_OVERSHOOT_DETECTOR_H_
79