/* * 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_JITTER_ESTIMATOR_H_ #define MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_ #include "absl/types/optional.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/rtt_filter.h" #include "rtc_base/rolling_accumulator.h" namespace webrtc { class Clock; class VCMJitterEstimator { public: explicit VCMJitterEstimator(Clock* clock); virtual ~VCMJitterEstimator(); VCMJitterEstimator(const VCMJitterEstimator&) = delete; VCMJitterEstimator& operator=(const VCMJitterEstimator&) = 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 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 last_update_time_; // The previously returned jitter estimate absl::optional prev_estimate_; // Frame size of the previous frame absl::optional 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_; VCMRttFilter rtt_filter_; // Tracks frame rates in microseconds. rtc::RollingAccumulator fps_counter_; const double time_deviation_upper_bound_; const bool enable_reduced_delay_; Clock* clock_; }; } // namespace webrtc #endif // MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_