17b15cb33847e6282ea8352c98894683b796127f3Wei Jia/*
27b15cb33847e6282ea8352c98894683b796127f3Wei Jia * Copyright (C) 2015 The Android Open Source Project
37b15cb33847e6282ea8352c98894683b796127f3Wei Jia *
47b15cb33847e6282ea8352c98894683b796127f3Wei Jia * Licensed under the Apache License, Version 2.0 (the "License");
57b15cb33847e6282ea8352c98894683b796127f3Wei Jia * you may not use this file except in compliance with the License.
67b15cb33847e6282ea8352c98894683b796127f3Wei Jia * You may obtain a copy of the License at
77b15cb33847e6282ea8352c98894683b796127f3Wei Jia *
87b15cb33847e6282ea8352c98894683b796127f3Wei Jia *      http://www.apache.org/licenses/LICENSE-2.0
97b15cb33847e6282ea8352c98894683b796127f3Wei Jia *
107b15cb33847e6282ea8352c98894683b796127f3Wei Jia * Unless required by applicable law or agreed to in writing, software
117b15cb33847e6282ea8352c98894683b796127f3Wei Jia * distributed under the License is distributed on an "AS IS" BASIS,
127b15cb33847e6282ea8352c98894683b796127f3Wei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137b15cb33847e6282ea8352c98894683b796127f3Wei Jia * See the License for the specific language governing permissions and
147b15cb33847e6282ea8352c98894683b796127f3Wei Jia * limitations under the License.
157b15cb33847e6282ea8352c98894683b796127f3Wei Jia */
167b15cb33847e6282ea8352c98894683b796127f3Wei Jia
177b15cb33847e6282ea8352c98894683b796127f3Wei Jia//#define LOG_NDEBUG 0
187b15cb33847e6282ea8352c98894683b796127f3Wei Jia#define LOG_TAG "MediaClock"
197b15cb33847e6282ea8352c98894683b796127f3Wei Jia#include <utils/Log.h>
2017648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia#include <map>
217b15cb33847e6282ea8352c98894683b796127f3Wei Jia
225833b6aad2c46ba516bdc8262f4fc4667e8018edWei Jia#include <media/stagefright/MediaClock.h>
237b15cb33847e6282ea8352c98894683b796127f3Wei Jia
249816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia#include <media/stagefright/foundation/ADebug.h>
257b6f67d18a4a4e94fddb836de1176b609968643aWei Jia#include <media/stagefright/foundation/AMessage.h>
267b15cb33847e6282ea8352c98894683b796127f3Wei Jia
277b15cb33847e6282ea8352c98894683b796127f3Wei Jianamespace android {
287b15cb33847e6282ea8352c98894683b796127f3Wei Jia
294ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia// Maximum allowed time backwards from anchor change.
304ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia// If larger than this threshold, it's treated as discontinuity.
314ecbea3ae1fcefb082dc419cb663909536138ddbWei Jiastatic const int64_t kAnchorFluctuationAllowedUs = 10000ll;
324ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia
3317648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei JiaMediaClock::Timer::Timer(const sp<AMessage> &notify, int64_t mediaTimeUs, int64_t adjustRealUs)
3417648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    : mNotify(notify),
3517648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia      mMediaTimeUs(mediaTimeUs),
3617648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia      mAdjustRealUs(adjustRealUs) {
3717648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia}
3817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia
397b15cb33847e6282ea8352c98894683b796127f3Wei JiaMediaClock::MediaClock()
407b15cb33847e6282ea8352c98894683b796127f3Wei Jia    : mAnchorTimeMediaUs(-1),
417b15cb33847e6282ea8352c98894683b796127f3Wei Jia      mAnchorTimeRealUs(-1),
427b15cb33847e6282ea8352c98894683b796127f3Wei Jia      mMaxTimeMediaUs(INT64_MAX),
437b15cb33847e6282ea8352c98894683b796127f3Wei Jia      mStartingTimeMediaUs(-1),
447b6f67d18a4a4e94fddb836de1176b609968643aWei Jia      mPlaybackRate(1.0),
457b6f67d18a4a4e94fddb836de1176b609968643aWei Jia      mGeneration(0) {
467b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    mLooper = new ALooper;
477b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    mLooper->setName("MediaClock");
487b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    mLooper->start(false /* runOnCallingThread */,
497b6f67d18a4a4e94fddb836de1176b609968643aWei Jia                   false /* canCallJava */,
507b6f67d18a4a4e94fddb836de1176b609968643aWei Jia                   ANDROID_PRIORITY_AUDIO);
517b6f67d18a4a4e94fddb836de1176b609968643aWei Jia}
527b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
537b6f67d18a4a4e94fddb836de1176b609968643aWei Jiavoid MediaClock::init() {
547b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    mLooper->registerHandler(this);
557b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
567b15cb33847e6282ea8352c98894683b796127f3Wei Jia
577b15cb33847e6282ea8352c98894683b796127f3Wei JiaMediaClock::~MediaClock() {
587b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    reset();
597b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    if (mLooper != NULL) {
607b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        mLooper->unregisterHandler(id());
617b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        mLooper->stop();
627b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
637b6f67d18a4a4e94fddb836de1176b609968643aWei Jia}
647b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
657b6f67d18a4a4e94fddb836de1176b609968643aWei Jiavoid MediaClock::reset() {
667b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    Mutex::Autolock autoLock(mLock);
677b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    auto it = mTimers.begin();
687b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    while (it != mTimers.end()) {
6917648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        it->mNotify->setInt32("reason", TIMER_REASON_RESET);
7017648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        it->mNotify->post();
717b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        it = mTimers.erase(it);
727b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
737b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    mMaxTimeMediaUs = INT64_MAX;
747b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    mStartingTimeMediaUs = -1;
7547afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    updateAnchorTimesAndPlaybackRate_l(-1, -1, 1.0);
767b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    ++mGeneration;
777b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
787b15cb33847e6282ea8352c98894683b796127f3Wei Jia
797b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) {
807b15cb33847e6282ea8352c98894683b796127f3Wei Jia    Mutex::Autolock autoLock(mLock);
817b15cb33847e6282ea8352c98894683b796127f3Wei Jia    mStartingTimeMediaUs = startingTimeMediaUs;
827b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
837b15cb33847e6282ea8352c98894683b796127f3Wei Jia
847b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid MediaClock::clearAnchor() {
857b15cb33847e6282ea8352c98894683b796127f3Wei Jia    Mutex::Autolock autoLock(mLock);
8647afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    updateAnchorTimesAndPlaybackRate_l(-1, -1, mPlaybackRate);
877b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
887b15cb33847e6282ea8352c98894683b796127f3Wei Jia
897b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid MediaClock::updateAnchor(
907b15cb33847e6282ea8352c98894683b796127f3Wei Jia        int64_t anchorTimeMediaUs,
917b15cb33847e6282ea8352c98894683b796127f3Wei Jia        int64_t anchorTimeRealUs,
927b15cb33847e6282ea8352c98894683b796127f3Wei Jia        int64_t maxTimeMediaUs) {
937b15cb33847e6282ea8352c98894683b796127f3Wei Jia    if (anchorTimeMediaUs < 0 || anchorTimeRealUs < 0) {
947b15cb33847e6282ea8352c98894683b796127f3Wei Jia        ALOGW("reject anchor time since it is negative.");
957b15cb33847e6282ea8352c98894683b796127f3Wei Jia        return;
967b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
977b15cb33847e6282ea8352c98894683b796127f3Wei Jia
989816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    Mutex::Autolock autoLock(mLock);
997b15cb33847e6282ea8352c98894683b796127f3Wei Jia    int64_t nowUs = ALooper::GetNowUs();
1009816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    int64_t nowMediaUs =
1019816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        anchorTimeMediaUs + (nowUs - anchorTimeRealUs) * (double)mPlaybackRate;
1027b15cb33847e6282ea8352c98894683b796127f3Wei Jia    if (nowMediaUs < 0) {
1037b15cb33847e6282ea8352c98894683b796127f3Wei Jia        ALOGW("reject anchor time since it leads to negative media time.");
1047b15cb33847e6282ea8352c98894683b796127f3Wei Jia        return;
1057b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
1064ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia
1074ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia    if (maxTimeMediaUs != -1) {
1084ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        mMaxTimeMediaUs = maxTimeMediaUs;
1094ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia    }
1104ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia    if (mAnchorTimeRealUs != -1) {
1114ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        int64_t oldNowMediaUs =
1124ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia            mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
1134ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        if (nowMediaUs < oldNowMediaUs
1144ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia                && nowMediaUs > oldNowMediaUs - kAnchorFluctuationAllowedUs) {
1154ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia            return;
1164ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        }
1174ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia    }
11847afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    updateAnchorTimesAndPlaybackRate_l(nowMediaUs, nowUs, mPlaybackRate);
1197b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
1207b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    ++mGeneration;
1217b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    processTimers_l();
1227b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
1237b15cb33847e6282ea8352c98894683b796127f3Wei Jia
1247b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) {
1257b15cb33847e6282ea8352c98894683b796127f3Wei Jia    Mutex::Autolock autoLock(mLock);
1267b15cb33847e6282ea8352c98894683b796127f3Wei Jia    mMaxTimeMediaUs = maxTimeMediaUs;
1277b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
1287b15cb33847e6282ea8352c98894683b796127f3Wei Jia
1299816016afb2a13c6a866cd047d57020566a8b9a9Wei Jiavoid MediaClock::setPlaybackRate(float rate) {
1309816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    CHECK_GE(rate, 0.0);
1317b15cb33847e6282ea8352c98894683b796127f3Wei Jia    Mutex::Autolock autoLock(mLock);
1327b15cb33847e6282ea8352c98894683b796127f3Wei Jia    if (mAnchorTimeRealUs == -1) {
1339816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        mPlaybackRate = rate;
1347b15cb33847e6282ea8352c98894683b796127f3Wei Jia        return;
1357b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
1367b15cb33847e6282ea8352c98894683b796127f3Wei Jia
1377b15cb33847e6282ea8352c98894683b796127f3Wei Jia    int64_t nowUs = ALooper::GetNowUs();
13847afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    int64_t nowMediaUs = mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
13947afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    if (nowMediaUs < 0) {
1409816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        ALOGW("setRate: anchor time should not be negative, set to 0.");
14147afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        nowMediaUs = 0;
1427b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
14347afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    updateAnchorTimesAndPlaybackRate_l(nowMediaUs, nowUs, rate);
1447b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
1457b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    if (rate > 0.0) {
1467b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        ++mGeneration;
1477b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        processTimers_l();
1487b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
1497b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
1507b15cb33847e6282ea8352c98894683b796127f3Wei Jia
151fa6a06765e7b92b7ba265482bd4cf3074f9ff6ccWei Jiafloat MediaClock::getPlaybackRate() const {
152fa6a06765e7b92b7ba265482bd4cf3074f9ff6ccWei Jia    Mutex::Autolock autoLock(mLock);
153fa6a06765e7b92b7ba265482bd4cf3074f9ff6ccWei Jia    return mPlaybackRate;
154fa6a06765e7b92b7ba265482bd4cf3074f9ff6ccWei Jia}
155fa6a06765e7b92b7ba265482bd4cf3074f9ff6ccWei Jia
1569816016afb2a13c6a866cd047d57020566a8b9a9Wei Jiastatus_t MediaClock::getMediaTime(
157c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia        int64_t realUs, int64_t *outMediaUs, bool allowPastMaxTime) const {
158c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia    if (outMediaUs == NULL) {
159c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia        return BAD_VALUE;
160c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia    }
161c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia
1627b15cb33847e6282ea8352c98894683b796127f3Wei Jia    Mutex::Autolock autoLock(mLock);
1639816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    return getMediaTime_l(realUs, outMediaUs, allowPastMaxTime);
1649816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia}
1657b15cb33847e6282ea8352c98894683b796127f3Wei Jia
1669816016afb2a13c6a866cd047d57020566a8b9a9Wei Jiastatus_t MediaClock::getMediaTime_l(
167c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia        int64_t realUs, int64_t *outMediaUs, bool allowPastMaxTime) const {
1687b15cb33847e6282ea8352c98894683b796127f3Wei Jia    if (mAnchorTimeRealUs == -1) {
1699816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        return NO_INIT;
1707b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
1717b15cb33847e6282ea8352c98894683b796127f3Wei Jia
1729816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    int64_t mediaUs = mAnchorTimeMediaUs
1739816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia            + (realUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
1749816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    if (mediaUs > mMaxTimeMediaUs && !allowPastMaxTime) {
1759816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        mediaUs = mMaxTimeMediaUs;
1769816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    }
1779816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    if (mediaUs < mStartingTimeMediaUs) {
1789816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        mediaUs = mStartingTimeMediaUs;
1799816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    }
1809816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    if (mediaUs < 0) {
1819816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        mediaUs = 0;
1829816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    }
1839816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    *outMediaUs = mediaUs;
1849816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    return OK;
1857b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
1867b15cb33847e6282ea8352c98894683b796127f3Wei Jia
187c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiastatus_t MediaClock::getRealTimeFor(
188c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia        int64_t targetMediaUs, int64_t *outRealUs) const {
189c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia    if (outRealUs == NULL) {
190c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia        return BAD_VALUE;
191c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia    }
192c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia
1937b15cb33847e6282ea8352c98894683b796127f3Wei Jia    Mutex::Autolock autoLock(mLock);
1949816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    if (mPlaybackRate == 0.0) {
1959816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        return NO_INIT;
1967b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
1977b15cb33847e6282ea8352c98894683b796127f3Wei Jia
1989816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    int64_t nowUs = ALooper::GetNowUs();
1999816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    int64_t nowMediaUs;
2009816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    status_t status =
2019816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia            getMediaTime_l(nowUs, &nowMediaUs, true /* allowPastMaxTime */);
2029816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    if (status != OK) {
2039816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        return status;
2047b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
2059816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    *outRealUs = (targetMediaUs - nowMediaUs) / (double)mPlaybackRate + nowUs;
2069816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    return OK;
2077b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
2087b15cb33847e6282ea8352c98894683b796127f3Wei Jia
20917648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jiavoid MediaClock::addTimer(const sp<AMessage> &notify, int64_t mediaTimeUs,
21017648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                          int64_t adjustRealUs) {
2117b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    Mutex::Autolock autoLock(mLock);
21217648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia
21317648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    bool updateTimer = (mPlaybackRate != 0.0);
21417648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    if (updateTimer) {
21517648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        auto it = mTimers.begin();
21617648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        while (it != mTimers.end()) {
21717648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            if (((it->mAdjustRealUs - (double)adjustRealUs) * (double)mPlaybackRate
21817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                + (it->mMediaTimeUs - mediaTimeUs)) <= 0) {
21917648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                updateTimer = false;
22017648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                break;
22117648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            }
22217648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            ++it;
22317648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        }
2247b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
2257b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
22617648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    mTimers.emplace_back(notify, mediaTimeUs, adjustRealUs);
22717648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia
22817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    if (updateTimer) {
2297b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        ++mGeneration;
2307b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        processTimers_l();
2317b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
2327b6f67d18a4a4e94fddb836de1176b609968643aWei Jia}
2337b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
2347b6f67d18a4a4e94fddb836de1176b609968643aWei Jiavoid MediaClock::onMessageReceived(const sp<AMessage> &msg) {
2357b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    switch (msg->what()) {
2367b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        case kWhatTimeIsUp:
2377b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        {
2387b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            int32_t generation;
2397b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            CHECK(msg->findInt32("generation", &generation));
2407b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
2417b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            Mutex::Autolock autoLock(mLock);
2427b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            if (generation != mGeneration) {
2437b6f67d18a4a4e94fddb836de1176b609968643aWei Jia                break;
2447b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            }
2457b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            processTimers_l();
2467b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            break;
2477b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        }
2487b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
2497b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        default:
2507b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            TRESPASS();
2517b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            break;
2527b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
2537b6f67d18a4a4e94fddb836de1176b609968643aWei Jia}
2547b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
2557b6f67d18a4a4e94fddb836de1176b609968643aWei Jiavoid MediaClock::processTimers_l() {
2567b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    int64_t nowMediaTimeUs;
2577b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    status_t status = getMediaTime_l(
2587b6f67d18a4a4e94fddb836de1176b609968643aWei Jia            ALooper::GetNowUs(), &nowMediaTimeUs, false /* allowPastMaxTime */);
2597b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
2607b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    if (status != OK) {
2617b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        return;
2627b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
2637b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
26417648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    int64_t nextLapseRealUs = INT64_MAX;
26517648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    std::multimap<int64_t, Timer> notifyList;
2667b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    auto it = mTimers.begin();
26717648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    while (it != mTimers.end()) {
26817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        double diff = it->mAdjustRealUs * (double)mPlaybackRate
26917648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            + it->mMediaTimeUs - nowMediaTimeUs;
27017648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        int64_t diffMediaUs;
27117648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        if (diff > (double)INT64_MAX) {
27217648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            diffMediaUs = INT64_MAX;
27317648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        } else if (diff < (double)INT64_MIN) {
27417648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            diffMediaUs = INT64_MIN;
27517648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        } else {
27617648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            diffMediaUs = diff;
27717648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        }
27817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia
27917648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        if (diffMediaUs <= 0) {
28017648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            notifyList.emplace(diffMediaUs, *it);
28117648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            it = mTimers.erase(it);
28217648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        } else {
28317648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            if (mPlaybackRate != 0.0
28417648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                && (double)diffMediaUs < INT64_MAX * (double)mPlaybackRate) {
28517648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                int64_t targetRealUs = diffMediaUs / (double)mPlaybackRate;
28617648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                if (targetRealUs < nextLapseRealUs) {
28717648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                    nextLapseRealUs = targetRealUs;
28817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia                }
28917648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            }
29017648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia            ++it;
29117648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        }
29217648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    }
29317648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia
29417648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    auto itNotify = notifyList.begin();
29517648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    while (itNotify != notifyList.end()) {
29617648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        itNotify->second.mNotify->setInt32("reason", TIMER_REASON_REACHED);
29717648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        itNotify->second.mNotify->post();
29817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        itNotify = notifyList.erase(itNotify);
2997b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
3007b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
30117648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    if (mTimers.empty() || mPlaybackRate == 0.0 || mAnchorTimeMediaUs < 0
30217648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia        || nextLapseRealUs == INT64_MAX) {
3037b6f67d18a4a4e94fddb836de1176b609968643aWei Jia        return;
3047b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    }
3057b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
3067b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    sp<AMessage> msg = new AMessage(kWhatTimeIsUp, this);
3077b6f67d18a4a4e94fddb836de1176b609968643aWei Jia    msg->setInt32("generation", mGeneration);
30817648f365e5914fa772bbfebaf9f5c6a37ddfb99Wei Jia    msg->post(nextLapseRealUs);
3097b6f67d18a4a4e94fddb836de1176b609968643aWei Jia}
3107b6f67d18a4a4e94fddb836de1176b609968643aWei Jia
31147afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kangvoid MediaClock::updateAnchorTimesAndPlaybackRate_l(int64_t anchorTimeMediaUs,
31247afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        int64_t anchorTimeRealUs, float playbackRate) {
31347afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    if (mAnchorTimeMediaUs != anchorTimeMediaUs
31447afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang            || mAnchorTimeRealUs != anchorTimeRealUs
31547afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang            || mPlaybackRate != playbackRate) {
31647afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        mAnchorTimeMediaUs = anchorTimeMediaUs;
31747afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        mAnchorTimeRealUs = anchorTimeRealUs;
31847afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        mPlaybackRate = playbackRate;
31947afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        notifyDiscontinuity_l();
32047afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    }
32147afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang}
32247afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang
32347afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kangvoid MediaClock::setNotificationMessage(const sp<AMessage> &msg) {
32447afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    Mutex::Autolock autoLock(mLock);
32547afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    mNotify = msg;
32647afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang}
32747afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang
32847afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kangvoid MediaClock::notifyDiscontinuity_l() {
32947afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    if (mNotify != nullptr) {
33047afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        sp<AMessage> msg = mNotify->dup();
33147afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        msg->setInt64("anchor-media-us", mAnchorTimeMediaUs);
33247afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        msg->setInt64("anchor-real-us", mAnchorTimeRealUs);
33347afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        msg->setFloat("playback-rate", mPlaybackRate);
33447afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang        msg->post();
33547afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang    }
33647afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang}
33747afe0a1a6f37e7807a81acb21ef588aec0a3518Dongwon Kang
3387b15cb33847e6282ea8352c98894683b796127f3Wei Jia}  // namespace android
339