blob: 7bfff135b4647ea9d98c99b9d4f9c7126014d1db [file] [log] [blame]
Wei Jia7b15cb32015-02-03 17:46:06 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "MediaClock"
19#include <utils/Log.h>
20
21#include "MediaClock.h"
22
23#include <media/stagefright/foundation/ALooper.h>
24
25namespace android {
26
27// Maximum time change between two updates.
28static const int64_t kMaxAnchorFluctuationUs = 1000ll;
29
30MediaClock::MediaClock()
31 : mAnchorTimeMediaUs(-1),
32 mAnchorTimeRealUs(-1),
33 mMaxTimeMediaUs(INT64_MAX),
34 mStartingTimeMediaUs(-1),
35 mPaused(false) {
36}
37
38MediaClock::~MediaClock() {
39}
40
41void MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) {
42 Mutex::Autolock autoLock(mLock);
43 mStartingTimeMediaUs = startingTimeMediaUs;
44}
45
46void MediaClock::clearAnchor() {
47 Mutex::Autolock autoLock(mLock);
48 mAnchorTimeMediaUs = -1;
49 mAnchorTimeRealUs = -1;
50}
51
52void MediaClock::updateAnchor(
53 int64_t anchorTimeMediaUs,
54 int64_t anchorTimeRealUs,
55 int64_t maxTimeMediaUs) {
56 if (anchorTimeMediaUs < 0 || anchorTimeRealUs < 0) {
57 ALOGW("reject anchor time since it is negative.");
58 return;
59 }
60
61 int64_t nowUs = ALooper::GetNowUs();
62 int64_t nowMediaUs = anchorTimeMediaUs + nowUs - anchorTimeRealUs;
63 if (nowMediaUs < 0) {
64 ALOGW("reject anchor time since it leads to negative media time.");
65 return;
66 }
67
68 Mutex::Autolock autoLock(mLock);
69 mAnchorTimeRealUs = nowUs;
70 mAnchorTimeMediaUs = nowMediaUs;
71 mMaxTimeMediaUs = maxTimeMediaUs;
72}
73
74void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) {
75 Mutex::Autolock autoLock(mLock);
76 mMaxTimeMediaUs = maxTimeMediaUs;
77}
78
79void MediaClock::pause() {
80 Mutex::Autolock autoLock(mLock);
81 if (mPaused) {
82 return;
83 }
84
85 mPaused = true;
86 if (mAnchorTimeRealUs == -1) {
87 return;
88 }
89
90 int64_t nowUs = ALooper::GetNowUs();
91 mAnchorTimeMediaUs += nowUs - mAnchorTimeRealUs;
92 if (mAnchorTimeMediaUs < 0) {
93 ALOGW("anchor time should not be negative, set to 0.");
94 mAnchorTimeMediaUs = 0;
95 }
96 mAnchorTimeRealUs = nowUs;
97}
98
99void MediaClock::resume() {
100 Mutex::Autolock autoLock(mLock);
101 if (!mPaused) {
102 return;
103 }
104
105 mPaused = false;
106 if (mAnchorTimeRealUs == -1) {
107 return;
108 }
109
110 mAnchorTimeRealUs = ALooper::GetNowUs();
111}
112
113int64_t MediaClock::getTimeMedia(int64_t realUs, bool allowPastMaxTime) {
114 Mutex::Autolock autoLock(mLock);
115 if (mAnchorTimeRealUs == -1) {
116 return -1ll;
117 }
118
119 if (mPaused) {
120 realUs = mAnchorTimeRealUs;
121 }
122 int64_t currentMediaUs = mAnchorTimeMediaUs + realUs - mAnchorTimeRealUs;
123 if (currentMediaUs > mMaxTimeMediaUs && !allowPastMaxTime) {
124 currentMediaUs = mMaxTimeMediaUs;
125 }
126 if (currentMediaUs < mStartingTimeMediaUs) {
127 currentMediaUs = mStartingTimeMediaUs;
128 }
129 if (currentMediaUs < 0) {
130 currentMediaUs = 0;
131 }
132 return currentMediaUs;
133}
134
135} // namespace android