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 #include "webrtc/modules/audio_conference_mixer/source/time_scheduler.h"
     12 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
     13 
     14 namespace webrtc {
     15 TimeScheduler::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 
     25 TimeScheduler::~TimeScheduler()
     26 {
     27     delete _crit;
     28 }
     29 
     30 int32_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 
     78 int32_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