summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/nuplayer/MediaClock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/MediaClock.cpp')
-rw-r--r--media/libmediaplayerservice/nuplayer/MediaClock.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/media/libmediaplayerservice/nuplayer/MediaClock.cpp b/media/libmediaplayerservice/nuplayer/MediaClock.cpp
new file mode 100644
index 0000000..7bfff13
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/MediaClock.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaClock"
+#include <utils/Log.h>
+
+#include "MediaClock.h"
+
+#include <media/stagefright/foundation/ALooper.h>
+
+namespace android {
+
+// Maximum time change between two updates.
+static const int64_t kMaxAnchorFluctuationUs = 1000ll;
+
+MediaClock::MediaClock()
+ : mAnchorTimeMediaUs(-1),
+ mAnchorTimeRealUs(-1),
+ mMaxTimeMediaUs(INT64_MAX),
+ mStartingTimeMediaUs(-1),
+ mPaused(false) {
+}
+
+MediaClock::~MediaClock() {
+}
+
+void MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) {
+ Mutex::Autolock autoLock(mLock);
+ mStartingTimeMediaUs = startingTimeMediaUs;
+}
+
+void MediaClock::clearAnchor() {
+ Mutex::Autolock autoLock(mLock);
+ mAnchorTimeMediaUs = -1;
+ mAnchorTimeRealUs = -1;
+}
+
+void MediaClock::updateAnchor(
+ int64_t anchorTimeMediaUs,
+ int64_t anchorTimeRealUs,
+ int64_t maxTimeMediaUs) {
+ if (anchorTimeMediaUs < 0 || anchorTimeRealUs < 0) {
+ ALOGW("reject anchor time since it is negative.");
+ return;
+ }
+
+ int64_t nowUs = ALooper::GetNowUs();
+ int64_t nowMediaUs = anchorTimeMediaUs + nowUs - anchorTimeRealUs;
+ if (nowMediaUs < 0) {
+ ALOGW("reject anchor time since it leads to negative media time.");
+ return;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+ mAnchorTimeRealUs = nowUs;
+ mAnchorTimeMediaUs = nowMediaUs;
+ mMaxTimeMediaUs = maxTimeMediaUs;
+}
+
+void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) {
+ Mutex::Autolock autoLock(mLock);
+ mMaxTimeMediaUs = maxTimeMediaUs;
+}
+
+void MediaClock::pause() {
+ Mutex::Autolock autoLock(mLock);
+ if (mPaused) {
+ return;
+ }
+
+ mPaused = true;
+ if (mAnchorTimeRealUs == -1) {
+ return;
+ }
+
+ int64_t nowUs = ALooper::GetNowUs();
+ mAnchorTimeMediaUs += nowUs - mAnchorTimeRealUs;
+ if (mAnchorTimeMediaUs < 0) {
+ ALOGW("anchor time should not be negative, set to 0.");
+ mAnchorTimeMediaUs = 0;
+ }
+ mAnchorTimeRealUs = nowUs;
+}
+
+void MediaClock::resume() {
+ Mutex::Autolock autoLock(mLock);
+ if (!mPaused) {
+ return;
+ }
+
+ mPaused = false;
+ if (mAnchorTimeRealUs == -1) {
+ return;
+ }
+
+ mAnchorTimeRealUs = ALooper::GetNowUs();
+}
+
+int64_t MediaClock::getTimeMedia(int64_t realUs, bool allowPastMaxTime) {
+ Mutex::Autolock autoLock(mLock);
+ if (mAnchorTimeRealUs == -1) {
+ return -1ll;
+ }
+
+ if (mPaused) {
+ realUs = mAnchorTimeRealUs;
+ }
+ int64_t currentMediaUs = mAnchorTimeMediaUs + realUs - mAnchorTimeRealUs;
+ if (currentMediaUs > mMaxTimeMediaUs && !allowPastMaxTime) {
+ currentMediaUs = mMaxTimeMediaUs;
+ }
+ if (currentMediaUs < mStartingTimeMediaUs) {
+ currentMediaUs = mStartingTimeMediaUs;
+ }
+ if (currentMediaUs < 0) {
+ currentMediaUs = 0;
+ }
+ return currentMediaUs;
+}
+
+} // namespace android