blob: 9152da1521b3d4a71963a1b3eeb3974c82435e3b [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
Wei Jia98160162015-02-04 17:01:11 -080023#include <media/stagefright/foundation/ADebug.h>
Wei Jia7b15cb32015-02-03 17:46:06 -080024#include <media/stagefright/foundation/ALooper.h>
25
26namespace android {
27
Wei Jia7b15cb32015-02-03 17:46:06 -080028MediaClock::MediaClock()
29 : mAnchorTimeMediaUs(-1),
30 mAnchorTimeRealUs(-1),
31 mMaxTimeMediaUs(INT64_MAX),
32 mStartingTimeMediaUs(-1),
Wei Jia98160162015-02-04 17:01:11 -080033 mPlaybackRate(1.0) {
Wei Jia7b15cb32015-02-03 17:46:06 -080034}
35
36MediaClock::~MediaClock() {
37}
38
39void MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) {
40 Mutex::Autolock autoLock(mLock);
41 mStartingTimeMediaUs = startingTimeMediaUs;
42}
43
44void MediaClock::clearAnchor() {
45 Mutex::Autolock autoLock(mLock);
46 mAnchorTimeMediaUs = -1;
47 mAnchorTimeRealUs = -1;
48}
49
50void MediaClock::updateAnchor(
51 int64_t anchorTimeMediaUs,
52 int64_t anchorTimeRealUs,
53 int64_t maxTimeMediaUs) {
54 if (anchorTimeMediaUs < 0 || anchorTimeRealUs < 0) {
55 ALOGW("reject anchor time since it is negative.");
56 return;
57 }
58
Wei Jia98160162015-02-04 17:01:11 -080059 Mutex::Autolock autoLock(mLock);
Wei Jia7b15cb32015-02-03 17:46:06 -080060 int64_t nowUs = ALooper::GetNowUs();
Wei Jia98160162015-02-04 17:01:11 -080061 int64_t nowMediaUs =
62 anchorTimeMediaUs + (nowUs - anchorTimeRealUs) * (double)mPlaybackRate;
Wei Jia7b15cb32015-02-03 17:46:06 -080063 if (nowMediaUs < 0) {
64 ALOGW("reject anchor time since it leads to negative media time.");
65 return;
66 }
Wei Jia7b15cb32015-02-03 17:46:06 -080067 mAnchorTimeRealUs = nowUs;
68 mAnchorTimeMediaUs = nowMediaUs;
69 mMaxTimeMediaUs = maxTimeMediaUs;
70}
71
72void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) {
73 Mutex::Autolock autoLock(mLock);
74 mMaxTimeMediaUs = maxTimeMediaUs;
75}
76
Wei Jia98160162015-02-04 17:01:11 -080077void MediaClock::setPlaybackRate(float rate) {
78 CHECK_GE(rate, 0.0);
Wei Jia7b15cb32015-02-03 17:46:06 -080079 Mutex::Autolock autoLock(mLock);
Wei Jia7b15cb32015-02-03 17:46:06 -080080 if (mAnchorTimeRealUs == -1) {
Wei Jia98160162015-02-04 17:01:11 -080081 mPlaybackRate = rate;
Wei Jia7b15cb32015-02-03 17:46:06 -080082 return;
83 }
84
85 int64_t nowUs = ALooper::GetNowUs();
Wei Jia98160162015-02-04 17:01:11 -080086 mAnchorTimeMediaUs += (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
Wei Jia7b15cb32015-02-03 17:46:06 -080087 if (mAnchorTimeMediaUs < 0) {
Wei Jia98160162015-02-04 17:01:11 -080088 ALOGW("setRate: anchor time should not be negative, set to 0.");
Wei Jia7b15cb32015-02-03 17:46:06 -080089 mAnchorTimeMediaUs = 0;
90 }
91 mAnchorTimeRealUs = nowUs;
Wei Jia98160162015-02-04 17:01:11 -080092 mPlaybackRate = rate;
Wei Jia7b15cb32015-02-03 17:46:06 -080093}
94
Wei Jia98160162015-02-04 17:01:11 -080095status_t MediaClock::getMediaTime(
96 int64_t realUs, int64_t *outMediaUs, bool allowPastMaxTime) {
Wei Jia7b15cb32015-02-03 17:46:06 -080097 Mutex::Autolock autoLock(mLock);
Wei Jia98160162015-02-04 17:01:11 -080098 return getMediaTime_l(realUs, outMediaUs, allowPastMaxTime);
Wei Jia7b15cb32015-02-03 17:46:06 -080099}
100
Wei Jia98160162015-02-04 17:01:11 -0800101status_t MediaClock::getMediaTime_l(
102 int64_t realUs, int64_t *outMediaUs, bool allowPastMaxTime) {
Wei Jia7b15cb32015-02-03 17:46:06 -0800103 if (mAnchorTimeRealUs == -1) {
Wei Jia98160162015-02-04 17:01:11 -0800104 return NO_INIT;
Wei Jia7b15cb32015-02-03 17:46:06 -0800105 }
106
Wei Jia98160162015-02-04 17:01:11 -0800107 int64_t mediaUs = mAnchorTimeMediaUs
108 + (realUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
109 if (mediaUs > mMaxTimeMediaUs && !allowPastMaxTime) {
110 mediaUs = mMaxTimeMediaUs;
Wei Jia7b15cb32015-02-03 17:46:06 -0800111 }
Wei Jia98160162015-02-04 17:01:11 -0800112 if (mediaUs < mStartingTimeMediaUs) {
113 mediaUs = mStartingTimeMediaUs;
Wei Jia7b15cb32015-02-03 17:46:06 -0800114 }
Wei Jia98160162015-02-04 17:01:11 -0800115 if (mediaUs < 0) {
116 mediaUs = 0;
Wei Jia7b15cb32015-02-03 17:46:06 -0800117 }
Wei Jia98160162015-02-04 17:01:11 -0800118 *outMediaUs = mediaUs;
119 return OK;
120}
121
122status_t MediaClock::getRealTimeFor(int64_t targetMediaUs, int64_t *outRealUs) {
123 Mutex::Autolock autoLock(mLock);
124 if (mPlaybackRate == 0.0) {
125 return NO_INIT;
Wei Jia7b15cb32015-02-03 17:46:06 -0800126 }
Wei Jia98160162015-02-04 17:01:11 -0800127
128 int64_t nowUs = ALooper::GetNowUs();
129 int64_t nowMediaUs;
130 status_t status =
131 getMediaTime_l(nowUs, &nowMediaUs, true /* allowPastMaxTime */);
132 if (status != OK) {
133 return status;
134 }
135 *outRealUs = (targetMediaUs - nowMediaUs) / (double)mPlaybackRate + nowUs;
136 return OK;
Wei Jia7b15cb32015-02-03 17:46:06 -0800137}
138
139} // namespace android