MediaClock: prevent media time from going backwards.
Media Clock is started only when AudioSink has rendered some frames.
Bug: 25074321
Change-Id: Ic09fc666eed019e24f5b6a4b8929021eab87ca41
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 879b825..c7456e9 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -313,8 +313,33 @@
msg->post();
}
-// Called on any threads.
+// Called on any threads without mLock acquired.
status_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) {
+ status_t result = mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
+ if (result == OK) {
+ return result;
+ }
+
+ // MediaClock has not started yet. Try to start it if possible.
+ {
+ Mutex::Autolock autoLock(mLock);
+ if (mAudioFirstAnchorTimeMediaUs == -1) {
+ return result;
+ }
+
+ AudioTimestamp ts;
+ status_t res = mAudioSink->getTimestamp(ts);
+ if (res != OK) {
+ return result;
+ }
+
+ // AudioSink has rendered some frames.
+ int64_t nowUs = ALooper::GetNowUs();
+ int64_t nowMediaUs = getPlayedOutAudioDurationUs(nowUs)
+ + mAudioFirstAnchorTimeMediaUs;
+ mMediaClock->updateAnchor(nowMediaUs, nowUs, -1);
+ }
+
return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
}
@@ -1010,9 +1035,14 @@
return;
}
setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
- int64_t nowUs = ALooper::GetNowUs();
- int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
- mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
+
+ AudioTimestamp ts;
+ status_t res = mAudioSink->getTimestamp(ts);
+ if (res == OK) {
+ int64_t nowUs = ALooper::GetNowUs();
+ int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
+ mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
+ }
mAnchorNumFramesWritten = mNumFramesWritten;
mAnchorTimeMediaUs = mediaTimeUs;
}
diff --git a/media/libstagefright/MediaClock.cpp b/media/libstagefright/MediaClock.cpp
index 2641e4e..3aa0061 100644
--- a/media/libstagefright/MediaClock.cpp
+++ b/media/libstagefright/MediaClock.cpp
@@ -25,6 +25,10 @@
namespace android {
+// Maximum allowed time backwards from anchor change.
+// If larger than this threshold, it's treated as discontinuity.
+static const int64_t kAnchorFluctuationAllowedUs = 10000ll;
+
MediaClock::MediaClock()
: mAnchorTimeMediaUs(-1),
mAnchorTimeRealUs(-1),
@@ -64,9 +68,20 @@
ALOGW("reject anchor time since it leads to negative media time.");
return;
}
+
+ if (maxTimeMediaUs != -1) {
+ mMaxTimeMediaUs = maxTimeMediaUs;
+ }
+ if (mAnchorTimeRealUs != -1) {
+ int64_t oldNowMediaUs =
+ mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
+ if (nowMediaUs < oldNowMediaUs
+ && nowMediaUs > oldNowMediaUs - kAnchorFluctuationAllowedUs) {
+ return;
+ }
+ }
mAnchorTimeRealUs = nowUs;
mAnchorTimeMediaUs = nowMediaUs;
- mMaxTimeMediaUs = maxTimeMediaUs;
}
void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) {