private float caclNextTimeStamp(float timestep) { // if it was not running just use last received value if (CurrentLocalTime < 0.0f) { float initBufferTime = Math.Max(_runningStats.AverageBufferTime, 0.08f); initBufferTime = Math.Min(initBufferTime, 0.05f); // start a bit conservative, give buffer time to fill up and avoid jitter in first few frames return(LastSnapshotLocalTime - initBufferTime); } // if there is a durable packet loss, skip updating stats and just pretend time passes as expected if (!_isNetworkHealthy) { return(CurrentLocalTime + timestep * 0.999f); // let's be a bit conservative } float nextTimeStamp = CurrentLocalTime + timestep; float bufferedTime = LastSnapshotLocalTime - nextTimeStamp; _runningStats.addSample(bufferedTime); // there is bad quality with current output time pace, slow down if it would help if (_runningStats.CurrentRateQuality < 0.85f && _runningStats.SlowDownIndicator >= _runningStats.CurrentRateQuality) { _runningStats.SlowDown(); return(nextTimeStamp - RunningStats.TimeStep); } // speed up if can have good quality with shorted buffer time if (_runningStats.SpeedUpIndicator > 0.95f) { _runningStats.SpeedUp(); return(nextTimeStamp + RunningStats.TimeStep); } return(nextTimeStamp); }