diff options
3 files changed, 67 insertions, 7 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index d050c78..e7e1759 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -380,13 +380,22 @@ status_t NuPlayerDriver::seekTo(int msec) { status_t NuPlayerDriver::getCurrentPosition(int *msec) { int64_t tempUs = 0; + { + Mutex::Autolock autoLock(mLock); + if (mSeekInProgress || mState == STATE_PAUSED) { + tempUs = (mPositionUs <= 0) ? 0 : mPositionUs; + *msec = (int)divRound(tempUs, (int64_t)(1000)); + return OK; + } + } + status_t ret = mPlayer->getCurrentPosition(&tempUs); Mutex::Autolock autoLock(mLock); // We need to check mSeekInProgress here because mPlayer->seekToAsync is an async call, which // means getCurrentPosition can be called before seek is completed. Iow, renderer may return a // position value that's different the seek to position. - if (ret != OK || mSeekInProgress) { + if (ret != OK) { tempUs = (mPositionUs <= 0) ? 0 : mPositionUs; } else { mPositionUs = tempUs; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index d6a828b..2ea6d70 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -68,6 +68,7 @@ NuPlayer::Renderer::Renderer( mNotifyCompleteVideo(false), mSyncQueues(false), mPaused(false), + mPausePositionMediaTimeUs(0), mVideoSampleReceived(false), mVideoRenderingStarted(false), mVideoRenderingStartGeneration(0), @@ -166,11 +167,48 @@ void NuPlayer::Renderer::setVideoFrameRate(float fps) { msg->post(); } +// Called on any threads, except renderer's thread. status_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) { - return getCurrentPosition(mediaUs, ALooper::GetNowUs()); + { + Mutex::Autolock autoLock(mLock); + int64_t currentPositionUs; + if (getCurrentPositionIfPaused_l(¤tPositionUs)) { + *mediaUs = currentPositionUs; + return OK; + } + } + return getCurrentPositionFromAnchor(mediaUs, ALooper::GetNowUs()); +} + +// Called on only renderer's thread. +status_t NuPlayer::Renderer::getCurrentPositionOnLooper(int64_t *mediaUs) { + return getCurrentPositionOnLooper(mediaUs, ALooper::GetNowUs()); } -status_t NuPlayer::Renderer::getCurrentPosition( +// Called on only renderer's thread. +// Since mPaused and mPausePositionMediaTimeUs are changed only on renderer's +// thread, no need to acquire mLock. +status_t NuPlayer::Renderer::getCurrentPositionOnLooper( + int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo) { + int64_t currentPositionUs; + if (getCurrentPositionIfPaused_l(¤tPositionUs)) { + *mediaUs = currentPositionUs; + return OK; + } + return getCurrentPositionFromAnchor(mediaUs, nowUs, allowPastQueuedVideo); +} + +// Called either with mLock acquired or on renderer's thread. +bool NuPlayer::Renderer::getCurrentPositionIfPaused_l(int64_t *mediaUs) { + if (!mPaused) { + return false; + } + *mediaUs = mPausePositionMediaTimeUs; + return true; +} + +// Called on any threads. +status_t NuPlayer::Renderer::getCurrentPositionFromAnchor( int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo) { Mutex::Autolock autoLock(mTimeLock); if (!mHasAudio && !mHasVideo) { @@ -718,7 +756,8 @@ int64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) { int64_t NuPlayer::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) { int64_t currentPositionUs; - if (getCurrentPosition(¤tPositionUs, nowUs, true /* allowPastQueuedVideo */) != OK) { + if (getCurrentPositionOnLooper( + ¤tPositionUs, nowUs, true /* allowPastQueuedVideo */) != OK) { // If failed to get current position, e.g. due to audio clock is not ready, then just // play out video immediately without delay. return nowUs; @@ -1179,6 +1218,11 @@ void NuPlayer::Renderer::onPause() { ALOGW("Renderer::onPause() called while already paused!"); return; } + int64_t currentPositionUs; + if (getCurrentPositionFromAnchor( + ¤tPositionUs, ALooper::GetNowUs()) == OK) { + mPausePositionMediaTimeUs = currentPositionUs; + } { Mutex::Autolock autoLock(mLock); ++mAudioQueueGeneration; @@ -1306,7 +1350,7 @@ void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reaso mAudioOffloadTornDown = true; int64_t currentPositionUs; - if (getCurrentPosition(¤tPositionUs) != OK) { + if (getCurrentPositionOnLooper(¤tPositionUs) != OK) { currentPositionUs = 0; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 406c64c..c6e3457 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -62,8 +62,6 @@ struct NuPlayer::Renderer : public AHandler { // Following setters and getters are protected by mTimeLock. status_t getCurrentPosition(int64_t *mediaUs); - status_t getCurrentPosition( - int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); void setHasMedia(bool audio); void setAudioFirstAnchorTime(int64_t mediaUs); void setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs); @@ -168,7 +166,10 @@ private: bool mSyncQueues; + // modified on only renderer's thread. bool mPaused; + int64_t mPausePositionMediaTimeUs; + bool mVideoSampleReceived; bool mVideoRenderingStarted; int32_t mVideoRenderingStartGeneration; @@ -183,6 +184,12 @@ private: int32_t mTotalBuffersQueued; int32_t mLastAudioBufferDrained; + status_t getCurrentPositionOnLooper(int64_t *mediaUs); + status_t getCurrentPositionOnLooper( + int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); + bool getCurrentPositionIfPaused_l(int64_t *mediaUs); + status_t getCurrentPositionFromAnchor( + int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); size_t fillAudioBuffer(void *buffer, size_t size); |