niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2011 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 | |
Rasmus Brandt | 10944e6 | 2022-05-25 10:12:42 +0200 | [diff] [blame] | 11 | #ifndef MODULES_VIDEO_CODING_TIMING_JITTER_ESTIMATOR_H_ |
| 12 | #define MODULES_VIDEO_CODING_TIMING_JITTER_ESTIMATOR_H_ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 13 | |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 14 | #include "absl/types/optional.h" |
Jonas Oreland | e62c2f2 | 2022-03-29 11:04:48 +0200 | [diff] [blame] | 15 | #include "api/field_trials_view.h" |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 16 | #include "api/units/data_size.h" |
| 17 | #include "api/units/frequency.h" |
| 18 | #include "api/units/time_delta.h" |
| 19 | #include "api/units/timestamp.h" |
Rasmus Brandt | 39ae696 | 2022-08-09 14:40:05 +0200 | [diff] [blame] | 20 | #include "modules/video_coding/timing/frame_delay_delta_kalman_filter.h" |
Rasmus Brandt | 2377226 | 2022-05-23 09:53:15 +0200 | [diff] [blame] | 21 | #include "modules/video_coding/timing/rtt_filter.h" |
Steve Anton | 10542f2 | 2019-01-11 09:11:00 -0800 | [diff] [blame] | 22 | #include "rtc_base/rolling_accumulator.h" |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 23 | |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 24 | namespace webrtc { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 25 | |
sprang@webrtc.org | 70e2d11 | 2014-09-24 14:06:56 +0000 | [diff] [blame] | 26 | class Clock; |
| 27 | |
Rasmus Brandt | 10944e6 | 2022-05-25 10:12:42 +0200 | [diff] [blame] | 28 | class JitterEstimator { |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 29 | public: |
Rasmus Brandt | 10944e6 | 2022-05-25 10:12:42 +0200 | [diff] [blame] | 30 | explicit JitterEstimator(Clock* clock, const FieldTrialsView& field_trials); |
Rasmus Brandt | 24a8e0d | 2022-08-12 16:39:25 +0200 | [diff] [blame] | 31 | ~JitterEstimator(); |
Rasmus Brandt | 10944e6 | 2022-05-25 10:12:42 +0200 | [diff] [blame] | 32 | JitterEstimator(const JitterEstimator&) = delete; |
| 33 | JitterEstimator& operator=(const JitterEstimator&) = delete; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 34 | |
Åsa Persson | 3fcc5be | 2019-04-04 09:40:27 +0200 | [diff] [blame] | 35 | // Resets the estimate to the initial state. |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 36 | void Reset(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 37 | |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 38 | // Updates the jitter estimate with the new data. |
| 39 | // |
| 40 | // Input: |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 41 | // - frame_delay : Delay-delta calculated by UTILDelayEstimate. |
| 42 | // - frame_size : Frame size of the current frame. |
philipel | e1c707c | 2022-07-05 14:03:25 +0200 | [diff] [blame] | 43 | void UpdateEstimate(TimeDelta frame_delay, DataSize frame_size); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 44 | |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 45 | // Returns the current jitter estimate and adds an RTT dependent term in cases |
| 46 | // of retransmission. |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 47 | // Input: |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 48 | // - rtt_multiplier : RTT param multiplier (when applicable). |
| 49 | // - rtt_mult_add_cap : Multiplier cap from the RTTMultExperiment. |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 50 | // |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 51 | // Return value : Jitter estimate. |
Rasmus Brandt | 24a8e0d | 2022-08-12 16:39:25 +0200 | [diff] [blame] | 52 | TimeDelta GetJitterEstimate(double rtt_multiplier, |
| 53 | absl::optional<TimeDelta> rtt_mult_add_cap); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 54 | |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 55 | // Updates the nack counter. |
| 56 | void FrameNacked(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 57 | |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 58 | // Updates the RTT filter. |
| 59 | // |
| 60 | // Input: |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 61 | // - rtt : Round trip time. |
| 62 | void UpdateRtt(TimeDelta rtt); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 63 | |
Åsa Persson | 3fcc5be | 2019-04-04 09:40:27 +0200 | [diff] [blame] | 64 | // A constant describing the delay from the jitter buffer to the delay on the |
| 65 | // receiving side which is not accounted for by the jitter buffer nor the |
| 66 | // decoding delay estimate. |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 67 | static constexpr TimeDelta OPERATING_SYSTEM_JITTER = TimeDelta::Millis(10); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 68 | |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 69 | private: |
Rasmus Brandt | 39ae696 | 2022-08-09 14:40:05 +0200 | [diff] [blame] | 70 | double var_noise_; // Variance of the time-deviation from the line |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 71 | |
Åsa Persson | 3fcc5be | 2019-04-04 09:40:27 +0200 | [diff] [blame] | 72 | // Updates the random jitter estimate, i.e. the variance of the time |
| 73 | // deviations from the line given by the Kalman filter. |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 74 | // |
| 75 | // Input: |
Åsa Persson | 3fcc5be | 2019-04-04 09:40:27 +0200 | [diff] [blame] | 76 | // - d_dT : The deviation from the kalman estimate. |
philipel | e1c707c | 2022-07-05 14:03:25 +0200 | [diff] [blame] | 77 | void EstimateRandomJitter(double d_dT); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 78 | |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 79 | double NoiseThreshold() const; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 80 | |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 81 | // Calculates the current jitter estimate. |
| 82 | // |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 83 | // Return value : The current jitter estimate. |
| 84 | TimeDelta CalculateEstimate(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 85 | |
Åsa Persson | 3fcc5be | 2019-04-04 09:40:27 +0200 | [diff] [blame] | 86 | // Post process the calculated estimate. |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 87 | void PostProcessEstimate(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 88 | |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 89 | Frequency GetFrameRate() const; |
sprang@webrtc.org | 70e2d11 | 2014-09-24 14:06:56 +0000 | [diff] [blame] | 90 | |
Rasmus Brandt | 39ae696 | 2022-08-09 14:40:05 +0200 | [diff] [blame] | 91 | // Filters the {frame_delay_delta, frame_size_delta} measurements through |
| 92 | // a linear Kalman filter. |
| 93 | FrameDelayDeltaKalmanFilter kalman_filter_; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 94 | |
philipel | 55a9a3d | 2022-08-19 13:23:26 +0200 | [diff] [blame] | 95 | // TODO(bugs.webrtc.org/14381): Update `avg_frame_size_bytes_` to DataSize |
| 96 | // when api/units have sufficient precision. |
| 97 | double avg_frame_size_bytes_; // Average frame size |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 98 | double var_frame_size_; // Frame size variance. Unit is bytes^2. |
| 99 | // Largest frame size received (descending with a factor kPsi) |
philipel | 55a9a3d | 2022-08-19 13:23:26 +0200 | [diff] [blame] | 100 | // TODO(bugs.webrtc.org/14381): Update `max_frame_size_bytes_` to DataSize |
| 101 | // when api/units have sufficient precision. |
| 102 | double max_frame_size_bytes_; |
| 103 | // TODO(bugs.webrtc.org/14381): Update `frame_size_sum_bytes_` to DataSize |
| 104 | // when api/units have sufficient precision. |
| 105 | double frame_size_sum_bytes_; |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 106 | uint32_t frame_size_count_; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 107 | |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 108 | absl::optional<Timestamp> last_update_time_; |
| 109 | // The previously returned jitter estimate |
| 110 | absl::optional<TimeDelta> prev_estimate_; |
| 111 | // Frame size of the previous frame |
| 112 | absl::optional<DataSize> prev_frame_size_; |
| 113 | // Average of the random jitter |
| 114 | double avg_noise_; |
| 115 | uint32_t alpha_count_; |
| 116 | // The filtered sum of jitter estimates |
| 117 | TimeDelta filter_jitter_estimate_ = TimeDelta::Zero(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 118 | |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 119 | uint32_t startup_count_; |
| 120 | // Time when the latest nack was seen |
| 121 | Timestamp latest_nack_ = Timestamp::Zero(); |
| 122 | // Keeps track of the number of nacks received, but never goes above |
| 123 | // kNackLimit. |
| 124 | uint32_t nack_count_; |
Rasmus Brandt | 2377226 | 2022-05-23 09:53:15 +0200 | [diff] [blame] | 125 | RttFilter rtt_filter_; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 126 | |
Evan Shrubsole | 13e42a8 | 2022-03-07 13:21:51 +0100 | [diff] [blame] | 127 | // Tracks frame rates in microseconds. |
philipel | 9d3ab61 | 2015-12-21 04:12:39 -0800 | [diff] [blame] | 128 | rtc::RollingAccumulator<uint64_t> fps_counter_; |
Sebastian Jansson | aa01f27 | 2019-01-30 11:28:59 +0100 | [diff] [blame] | 129 | Clock* clock_; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 130 | }; |
| 131 | |
pbos@webrtc.org | d900e8b | 2013-07-03 15:12:26 +0000 | [diff] [blame] | 132 | } // namespace webrtc |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 133 | |
Rasmus Brandt | 10944e6 | 2022-05-25 10:12:42 +0200 | [diff] [blame] | 134 | #endif // MODULES_VIDEO_CODING_TIMING_JITTER_ESTIMATOR_H_ |