| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef MODULES_VIDEO_CODING_TIMING_JITTER_ESTIMATOR_H_ |
| #define MODULES_VIDEO_CODING_TIMING_JITTER_ESTIMATOR_H_ |
| |
| #include "absl/types/optional.h" |
| #include "api/field_trials_view.h" |
| #include "api/units/data_size.h" |
| #include "api/units/frequency.h" |
| #include "api/units/time_delta.h" |
| #include "api/units/timestamp.h" |
| #include "modules/video_coding/timing/rtt_filter.h" |
| #include "rtc_base/rolling_accumulator.h" |
| |
| namespace webrtc { |
| |
| class Clock; |
| |
| class JitterEstimator { |
| public: |
| explicit JitterEstimator(Clock* clock, const FieldTrialsView& field_trials); |
| virtual ~JitterEstimator(); |
| JitterEstimator(const JitterEstimator&) = delete; |
| JitterEstimator& operator=(const JitterEstimator&) = delete; |
| |
| // Resets the estimate to the initial state. |
| void Reset(); |
| |
| // Updates the jitter estimate with the new data. |
| // |
| // Input: |
| // - frame_delay : Delay-delta calculated by UTILDelayEstimate. |
| // - frame_size : Frame size of the current frame. |
| // - incomplete_frame : Flags if the frame is used to update the |
| // estimate before it was complete. |
| // Default is false. |
| void UpdateEstimate(TimeDelta frame_delay, |
| DataSize frame_size, |
| bool incomplete_frame = false); |
| |
| // Returns the current jitter estimate and adds an RTT dependent term in cases |
| // of retransmission. |
| // Input: |
| // - rtt_multiplier : RTT param multiplier (when applicable). |
| // - rtt_mult_add_cap : Multiplier cap from the RTTMultExperiment. |
| // |
| // Return value : Jitter estimate. |
| virtual TimeDelta GetJitterEstimate( |
| double rtt_multiplier, |
| absl::optional<TimeDelta> rtt_mult_add_cap); |
| |
| // Updates the nack counter. |
| void FrameNacked(); |
| |
| // Updates the RTT filter. |
| // |
| // Input: |
| // - rtt : Round trip time. |
| void UpdateRtt(TimeDelta rtt); |
| |
| // A constant describing the delay from the jitter buffer to the delay on the |
| // receiving side which is not accounted for by the jitter buffer nor the |
| // decoding delay estimate. |
| static constexpr TimeDelta OPERATING_SYSTEM_JITTER = TimeDelta::Millis(10); |
| |
| protected: |
| // These are protected for better testing possibilities. |
| double theta_[2]; // Estimated line parameters (slope, offset) |
| double var_noise_; // Variance of the time-deviation from the line |
| |
| private: |
| // Updates the Kalman filter for the line describing the frame size dependent |
| // jitter. |
| // |
| // Input: |
| // - frame_delay |
| // Delay-delta calculated by UTILDelayEstimate. |
| // - delta_frame_size_bytes |
| // Frame size delta, i.e. frame size at time T minus frame size |
| // at time T-1. |
| void KalmanEstimateChannel(TimeDelta frame_delay, |
| double delta_frame_size_bytes); |
| |
| // Updates the random jitter estimate, i.e. the variance of the time |
| // deviations from the line given by the Kalman filter. |
| // |
| // Input: |
| // - d_dT : The deviation from the kalman estimate. |
| // - incomplete_frame : True if the frame used to update the |
| // estimate with was incomplete. |
| void EstimateRandomJitter(double d_dT, bool incomplete_frame); |
| |
| double NoiseThreshold() const; |
| |
| // Calculates the current jitter estimate. |
| // |
| // Return value : The current jitter estimate. |
| TimeDelta CalculateEstimate(); |
| |
| // Post process the calculated estimate. |
| void PostProcessEstimate(); |
| |
| // Calculates the difference in delay between a sample and the expected delay |
| // estimated by the Kalman filter. |
| // |
| // Input: |
| // - frame_delay : Delay-delta calculated by UTILDelayEstimate. |
| // - delta_frame_size_bytes : Frame size delta, i.e. frame size at |
| // time |
| // T minus frame size at time T-1. |
| // |
| // Return value : The delay difference in ms. |
| double DeviationFromExpectedDelay(TimeDelta frame_delay, |
| double delta_frame_size_bytes) const; |
| |
| Frequency GetFrameRate() const; |
| |
| double theta_cov_[2][2]; // Estimate covariance |
| double q_cov_[2][2]; // Process noise covariance |
| |
| static constexpr DataSize kDefaultAvgAndMaxFrameSize = DataSize::Bytes(500); |
| DataSize avg_frame_size_ = kDefaultAvgAndMaxFrameSize; // Average frame size |
| double var_frame_size_; // Frame size variance. Unit is bytes^2. |
| // Largest frame size received (descending with a factor kPsi) |
| DataSize max_frame_size_ = kDefaultAvgAndMaxFrameSize; |
| DataSize frame_size_sum_ = DataSize::Zero(); |
| uint32_t frame_size_count_; |
| |
| absl::optional<Timestamp> last_update_time_; |
| // The previously returned jitter estimate |
| absl::optional<TimeDelta> prev_estimate_; |
| // Frame size of the previous frame |
| absl::optional<DataSize> prev_frame_size_; |
| // Average of the random jitter |
| double avg_noise_; |
| uint32_t alpha_count_; |
| // The filtered sum of jitter estimates |
| TimeDelta filter_jitter_estimate_ = TimeDelta::Zero(); |
| |
| uint32_t startup_count_; |
| // Time when the latest nack was seen |
| Timestamp latest_nack_ = Timestamp::Zero(); |
| // Keeps track of the number of nacks received, but never goes above |
| // kNackLimit. |
| uint32_t nack_count_; |
| RttFilter rtt_filter_; |
| |
| // Tracks frame rates in microseconds. |
| rtc::RollingAccumulator<uint64_t> fps_counter_; |
| const double time_deviation_upper_bound_; |
| const bool enable_reduced_delay_; |
| Clock* clock_; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // MODULES_VIDEO_CODING_TIMING_JITTER_ESTIMATOR_H_ |