diff options
Diffstat (limited to 'media/libmediaplayerservice/nuplayer')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 60 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h | 3 |
2 files changed, 40 insertions, 23 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 067784b..8ab777a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -343,15 +343,13 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) { mFirstAudioTimeUs = mediaTimeUs; } - uint32_t numFramesPlayed; - CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); - - // TODO: figure out how to calculate initial latency. - // Otherwise, the initial time is not correct till the first sample - // is played. - mAnchorTimeMediaUs = mFirstAudioTimeUs - + (numFramesPlayed * mAudioSink->msecsPerFrame()) * 1000ll; - mAnchorTimeRealUs = ALooper::GetNowUs(); + // TODO: figure out how to calculate initial latency if + // getTimestamp is not available. Otherwise, the initial time + // is not correct till the first sample is played. + int64_t nowUs = ALooper::GetNowUs(); + mAnchorTimeMediaUs = + mFirstAudioTimeUs + getPlayedOutAudioDurationUs(nowUs); + mAnchorTimeRealUs = nowUs; } size_t copy = entry->mBuffer->size() - entry->mOffset; @@ -413,7 +411,7 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { // EOS int64_t postEOSDelayUs = 0; if (mAudioSink->needsTrailingPadding()) { - postEOSDelayUs = getAudioPendingPlayoutUs() + 1000 * mAudioSink->latency(); + postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs()); } notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs); @@ -428,8 +426,8 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6); mAnchorTimeMediaUs = mediaTimeUs; - mAnchorTimeRealUs = ALooper::GetNowUs() - + getAudioPendingPlayoutUs() + 1000 * mAudioSink->latency() / 2; + int64_t nowUs = ALooper::GetNowUs(); + mAnchorTimeRealUs = nowUs + getPendingAudioPlayoutDurationUs(nowUs); } size_t copy = entry->mBuffer->size() - entry->mOffset; @@ -483,12 +481,10 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { return !mAudioQueue.empty(); } -int64_t NuPlayer::Renderer::getAudioPendingPlayoutUs() { - uint32_t numFramesPlayed; - CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); - - uint32_t numFramesPendingPlayout = mNumFramesWritten - numFramesPlayed; - return numFramesPendingPlayout * mAudioSink->msecsPerFrame() * 1000; +int64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) { + int64_t writtenAudioDurationUs = + mNumFramesWritten * 1000LL * mAudioSink->msecsPerFrame(); + return writtenAudioDurationUs - getPlayedOutAudioDurationUs(nowUs); } void NuPlayer::Renderer::postDrainVideoQueue() { @@ -937,17 +933,37 @@ void NuPlayer::Renderer::onResume() { } } -void NuPlayer::Renderer::onAudioOffloadTearDown() { +int64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) { + // FIXME: getTimestamp sometimes returns negative frame count. + // Since we do not handle the rollover at this point (which can + // happen every 14 hours), simply treat the timestamp as signed. uint32_t numFramesPlayed; - CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); + int64_t numFramesPlayedAt; + AudioTimestamp ts; + status_t res = mAudioSink->getTimestamp(ts); + if (res == OK) { + numFramesPlayed = ts.mPosition; + numFramesPlayedAt = + ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000; + } else { + res = mAudioSink->getPosition(&numFramesPlayed); + CHECK_EQ(res, (status_t)OK); + numFramesPlayedAt = nowUs; + numFramesPlayedAt += 1000LL * mAudioSink->latency() / 2; /* XXX */ + } + return (int32_t)numFramesPlayed * 1000LL * mAudioSink->msecsPerFrame() + + nowUs - numFramesPlayedAt; +} +void NuPlayer::Renderer::onAudioOffloadTearDown() { int64_t firstAudioTimeUs; { Mutex::Autolock autoLock(mLock); firstAudioTimeUs = mFirstAudioTimeUs; } - int64_t currentPositionUs = firstAudioTimeUs - + (numFramesPlayed * mAudioSink->msecsPerFrame()) * 1000ll; + + int64_t currentPositionUs = + firstAudioTimeUs + getPlayedOutAudioDurationUs(ALooper::GetNowUs()); mAudioSink->stop(); mAudioSink->flush(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 5c7d2d7..2b32c48 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -130,7 +130,8 @@ private: size_t fillAudioBuffer(void *buffer, size_t size); bool onDrainAudioQueue(); - int64_t getAudioPendingPlayoutUs(); + int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs); + int64_t getPlayedOutAudioDurationUs(int64_t nowUs); void postDrainAudioQueue_l(int64_t delayUs = 0); void onDrainVideoQueue(); |