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 #include "webrtc/modules/audio_conference_mixer/source/time_scheduler.h" 12 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 13 14 namespace webrtc { TimeScheduler(const int64_t periodicityInMs)15TimeScheduler::TimeScheduler(const int64_t periodicityInMs) 16 : _crit(CriticalSectionWrapper::CreateCriticalSection()), 17 _isStarted(false), 18 _lastPeriodMark(), 19 _periodicityInMs(periodicityInMs), 20 _periodicityInTicks(TickTime::MillisecondsToTicks(periodicityInMs)), 21 _missedPeriods(0) 22 { 23 } 24 ~TimeScheduler()25TimeScheduler::~TimeScheduler() 26 { 27 delete _crit; 28 } 29 UpdateScheduler()30int32_t TimeScheduler::UpdateScheduler() 31 { 32 CriticalSectionScoped cs(_crit); 33 if(!_isStarted) 34 { 35 _isStarted = true; 36 _lastPeriodMark = TickTime::Now(); 37 return 0; 38 } 39 // Don't perform any calculations until the debt of pending periods have 40 // been worked off. 41 if(_missedPeriods > 0) 42 { 43 _missedPeriods--; 44 return 0; 45 } 46 47 // Calculate the time that has past since previous call to this function. 48 TickTime tickNow = TickTime::Now(); 49 TickInterval amassedTicks = tickNow - _lastPeriodMark; 50 int64_t amassedMs = amassedTicks.Milliseconds(); 51 52 // Calculate the number of periods the time that has passed correspond to. 53 int64_t periodsToClaim = amassedMs / _periodicityInMs; 54 55 // One period will be worked off by this call. Make sure that the number of 56 // pending periods don't end up being negative (e.g. if this function is 57 // called to often). 58 if(periodsToClaim < 1) 59 { 60 periodsToClaim = 1; 61 } 62 63 // Update the last period mark without introducing any drifting. 64 // Note that if this fuunction is called to often _lastPeriodMark can 65 // refer to a time in the future which in turn will yield TimeToNextUpdate 66 // that is greater than the periodicity 67 for(int64_t i = 0; i < periodsToClaim; i++) 68 { 69 _lastPeriodMark += _periodicityInTicks; 70 } 71 72 // Update the total amount of missed periods note that we have processed 73 // one period hence the - 1 74 _missedPeriods += periodsToClaim - 1; 75 return 0; 76 } 77 TimeToNextUpdate(int64_t & updateTimeInMS) const78int32_t TimeScheduler::TimeToNextUpdate( 79 int64_t& updateTimeInMS) const 80 { 81 CriticalSectionScoped cs(_crit); 82 // Missed periods means that the next UpdateScheduler() should happen 83 // immediately. 84 if(_missedPeriods > 0) 85 { 86 updateTimeInMS = 0; 87 return 0; 88 } 89 90 // Calculate the time (in ms) that has past since last call to 91 // UpdateScheduler() 92 TickTime tickNow = TickTime::Now(); 93 TickInterval ticksSinceLastUpdate = tickNow - _lastPeriodMark; 94 const int64_t millisecondsSinceLastUpdate = 95 ticksSinceLastUpdate.Milliseconds(); 96 97 updateTimeInMS = _periodicityInMs - millisecondsSinceLastUpdate; 98 updateTimeInMS = (updateTimeInMS < 0) ? 0 : updateTimeInMS; 99 return 0; 100 } 101 } // namespace webrtc 102