• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)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 
~TimeScheduler()25 TimeScheduler::~TimeScheduler()
26 {
27     delete _crit;
28 }
29 
UpdateScheduler()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 
TimeToNextUpdate(int64_t & updateTimeInMS) const78 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