Loading include/media/MediaPlayerInterface.h +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <media/mediaplayer.h> #include <media/AudioSystem.h> #include <media/AudioTimestamp.h> #include <media/Metadata.h> // Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is Loading Loading @@ -97,6 +98,7 @@ public: virtual uint32_t latency() const = 0; virtual float msecsPerFrame() const = 0; virtual status_t getPosition(uint32_t *position) const = 0; virtual status_t getTimestamp(AudioTimestamp &ts) const = 0; virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0; virtual int getSessionId() const = 0; virtual audio_stream_type_t getAudioStreamType() const = 0; Loading media/libmediaplayerservice/MediaPlayerService.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <utils/Errors.h> // for status_t #include <utils/String8.h> #include <utils/SystemClock.h> #include <utils/Timers.h> #include <utils/Vector.h> #include <media/IMediaHTTPService.h> Loading Loading @@ -1496,6 +1497,12 @@ status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const return mTrack->getPosition(position); } status_t MediaPlayerService::AudioOutput::getTimestamp(AudioTimestamp &ts) const { if (mTrack == 0) return NO_INIT; return mTrack->getTimestamp(ts); } status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const { if (mTrack == 0) return NO_INIT; Loading Loading @@ -1971,6 +1978,15 @@ status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) const return NO_ERROR; } status_t MediaPlayerService::AudioCache::getTimestamp(AudioTimestamp &ts) const { ts.mPosition = mSize / mFrameSize; nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); ts.mTime.tv_sec = now / 1000000000LL; ts.mTime.tv_nsec = now - (1000000000LL * ts.mTime.tv_sec); return NO_ERROR; } status_t MediaPlayerService::AudioCache::getFramesWritten(uint32_t *written) const { if (written == 0) return BAD_VALUE; Loading media/libmediaplayerservice/MediaPlayerService.h +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual uint32_t latency() const; virtual float msecsPerFrame() const; virtual status_t getPosition(uint32_t *position) const; virtual status_t getTimestamp(AudioTimestamp &ts) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; virtual uint32_t getSampleRate() const; Loading Loading @@ -198,6 +199,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual uint32_t latency() const; virtual float msecsPerFrame() const; virtual status_t getPosition(uint32_t *position) const; virtual status_t getTimestamp(AudioTimestamp &ts) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; virtual uint32_t getSampleRate() const; Loading media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +38 −22 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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(); Loading media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +2 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading
include/media/MediaPlayerInterface.h +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <media/mediaplayer.h> #include <media/AudioSystem.h> #include <media/AudioTimestamp.h> #include <media/Metadata.h> // Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is Loading Loading @@ -97,6 +98,7 @@ public: virtual uint32_t latency() const = 0; virtual float msecsPerFrame() const = 0; virtual status_t getPosition(uint32_t *position) const = 0; virtual status_t getTimestamp(AudioTimestamp &ts) const = 0; virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0; virtual int getSessionId() const = 0; virtual audio_stream_type_t getAudioStreamType() const = 0; Loading
media/libmediaplayerservice/MediaPlayerService.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <utils/Errors.h> // for status_t #include <utils/String8.h> #include <utils/SystemClock.h> #include <utils/Timers.h> #include <utils/Vector.h> #include <media/IMediaHTTPService.h> Loading Loading @@ -1496,6 +1497,12 @@ status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const return mTrack->getPosition(position); } status_t MediaPlayerService::AudioOutput::getTimestamp(AudioTimestamp &ts) const { if (mTrack == 0) return NO_INIT; return mTrack->getTimestamp(ts); } status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const { if (mTrack == 0) return NO_INIT; Loading Loading @@ -1971,6 +1978,15 @@ status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) const return NO_ERROR; } status_t MediaPlayerService::AudioCache::getTimestamp(AudioTimestamp &ts) const { ts.mPosition = mSize / mFrameSize; nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); ts.mTime.tv_sec = now / 1000000000LL; ts.mTime.tv_nsec = now - (1000000000LL * ts.mTime.tv_sec); return NO_ERROR; } status_t MediaPlayerService::AudioCache::getFramesWritten(uint32_t *written) const { if (written == 0) return BAD_VALUE; Loading
media/libmediaplayerservice/MediaPlayerService.h +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual uint32_t latency() const; virtual float msecsPerFrame() const; virtual status_t getPosition(uint32_t *position) const; virtual status_t getTimestamp(AudioTimestamp &ts) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; virtual uint32_t getSampleRate() const; Loading Loading @@ -198,6 +199,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual uint32_t latency() const; virtual float msecsPerFrame() const; virtual status_t getPosition(uint32_t *position) const; virtual status_t getTimestamp(AudioTimestamp &ts) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; virtual uint32_t getSampleRate() const; Loading
media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +38 −22 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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(); Loading
media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +2 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading