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