Home | History | Annotate | Download | only in source
      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 
     11 #ifndef WEBRTC_MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
     12 #define WEBRTC_MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
     13 
     14 #include "webrtc/base/rollingaccumulator.h"
     15 #include "webrtc/modules/video_coding/main/source/rtt_filter.h"
     16 #include "webrtc/typedefs.h"
     17 
     18 namespace webrtc
     19 {
     20 
     21 class Clock;
     22 
     23 class VCMJitterEstimator
     24 {
     25 public:
     26     VCMJitterEstimator(const Clock* clock,
     27                        int32_t vcmId = 0,
     28                        int32_t receiverId = 0);
     29     virtual ~VCMJitterEstimator();
     30     VCMJitterEstimator& operator=(const VCMJitterEstimator& rhs);
     31 
     32     // Resets the estimate to the initial state
     33     void Reset();
     34     void ResetNackCount();
     35 
     36     // Updates the jitter estimate with the new data.
     37     //
     38     // Input:
     39     //          - frameDelay      : Delay-delta calculated by UTILDelayEstimate in milliseconds
     40     //          - frameSize       : Frame size of the current frame.
     41     //          - incompleteFrame : Flags if the frame is used to update the estimate before it
     42     //                              was complete. Default is false.
     43     void UpdateEstimate(int64_t frameDelayMS,
     44                         uint32_t frameSizeBytes,
     45                         bool incompleteFrame = false);
     46 
     47     // Returns the current jitter estimate in milliseconds and adds
     48     // also adds an RTT dependent term in cases of retransmission.
     49     //  Input:
     50     //          - rttMultiplier  : RTT param multiplier (when applicable).
     51     //
     52     // Return value                   : Jitter estimate in milliseconds
     53     int GetJitterEstimate(double rttMultiplier);
     54 
     55     // Updates the nack counter.
     56     void FrameNacked();
     57 
     58     // Updates the RTT filter.
     59     //
     60     // Input:
     61     //          - rttMs               : RTT in ms
     62     void UpdateRtt(uint32_t rttMs);
     63 
     64     void UpdateMaxFrameSize(uint32_t frameSizeBytes);
     65 
     66     // A constant describing the delay from the jitter buffer
     67     // to the delay on the receiving side which is not accounted
     68     // for by the jitter buffer nor the decoding delay estimate.
     69     static const uint32_t OPERATING_SYSTEM_JITTER = 10;
     70 
     71 protected:
     72     // These are protected for better testing possibilities
     73     double              _theta[2]; // Estimated line parameters (slope, offset)
     74     double              _varNoise; // Variance of the time-deviation from the line
     75 
     76     virtual bool LowRateExperimentEnabled();
     77 
     78 private:
     79     // Updates the Kalman filter for the line describing
     80     // the frame size dependent jitter.
     81     //
     82     // Input:
     83     //          - frameDelayMS    : Delay-delta calculated by UTILDelayEstimate in milliseconds
     84     //          - deltaFSBytes    : Frame size delta, i.e.
     85     //                            : frame size at time T minus frame size at time T-1
     86     void KalmanEstimateChannel(int64_t frameDelayMS, int32_t deltaFSBytes);
     87 
     88     // Updates the random jitter estimate, i.e. the variance
     89     // of the time deviations from the line given by the Kalman filter.
     90     //
     91     // Input:
     92     //          - d_dT              : The deviation from the kalman estimate
     93     //          - incompleteFrame   : True if the frame used to update the estimate
     94     //                                with was incomplete
     95     void EstimateRandomJitter(double d_dT, bool incompleteFrame);
     96 
     97     double NoiseThreshold() const;
     98 
     99     // Calculates the current jitter estimate.
    100     //
    101     // Return value                 : The current jitter estimate in milliseconds
    102     double CalculateEstimate();
    103 
    104     // Post process the calculated estimate
    105     void PostProcessEstimate();
    106 
    107     // Calculates the difference in delay between a sample and the
    108     // expected delay estimated by the Kalman filter.
    109     //
    110     // Input:
    111     //          - frameDelayMS    : Delay-delta calculated by UTILDelayEstimate in milliseconds
    112     //          - deltaFS         : Frame size delta, i.e. frame size at time
    113     //                              T minus frame size at time T-1
    114     //
    115     // Return value                 : The difference in milliseconds
    116     double DeviationFromExpectedDelay(int64_t frameDelayMS,
    117                                       int32_t deltaFSBytes) const;
    118 
    119     double GetFrameRate() const;
    120 
    121     // Constants, filter parameters
    122     int32_t         _vcmId;
    123     int32_t         _receiverId;
    124     const double          _phi;
    125     const double          _psi;
    126     const uint32_t  _alphaCountMax;
    127     const double          _thetaLow;
    128     const uint32_t  _nackLimit;
    129     const int32_t   _numStdDevDelayOutlier;
    130     const int32_t   _numStdDevFrameSizeOutlier;
    131     const double          _noiseStdDevs;
    132     const double          _noiseStdDevOffset;
    133 
    134     double                _thetaCov[2][2]; // Estimate covariance
    135     double                _Qcov[2][2];     // Process noise covariance
    136     double                _avgFrameSize;   // Average frame size
    137     double                _varFrameSize;   // Frame size variance
    138     double                _maxFrameSize;   // Largest frame size received (descending
    139                                            // with a factor _psi)
    140     uint32_t        _fsSum;
    141     uint32_t        _fsCount;
    142 
    143     int64_t         _lastUpdateT;
    144     double                _prevEstimate;         // The previously returned jitter estimate
    145     uint32_t        _prevFrameSize;        // Frame size of the previous frame
    146     double                _avgNoise;             // Average of the random jitter
    147     uint32_t        _alphaCount;
    148     double                _filterJitterEstimate; // The filtered sum of jitter estimates
    149 
    150     uint32_t        _startupCount;
    151 
    152     int64_t         _latestNackTimestamp;  // Timestamp in ms when the latest nack was seen
    153     uint32_t        _nackCount;            // Keeps track of the number of nacks received,
    154                                                  // but never goes above _nackLimit
    155     VCMRttFilter          _rttFilter;
    156 
    157     rtc::RollingAccumulator<uint64_t> fps_counter_;
    158     enum ExperimentFlag { kInit, kEnabled, kDisabled };
    159     ExperimentFlag low_rate_experiment_;
    160     const Clock* clock_;
    161 };
    162 
    163 }  // namespace webrtc
    164 
    165 #endif // WEBRTC_MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
    166