summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-08-28 07:27:44 -0700
committerLajos Molnar <lajos@google.com>2014-09-17 23:01:24 +0000
commit06ad1528e6dd4c866c085d3cad9235d2752eb3ed (patch)
tree4b8411a9c418927b3916d5b5381cc8738a3ccb31
parent919b93473ebbba036f3934e92039f038c7f91a54 (diff)
downloadframeworks_av-06ad1528e6dd4c866c085d3cad9235d2752eb3ed.zip
frameworks_av-06ad1528e6dd4c866c085d3cad9235d2752eb3ed.tar.gz
frameworks_av-06ad1528e6dd4c866c085d3cad9235d2752eb3ed.tar.bz2
NuPlayer: use getTimestamp instead of getPosition
Bug: 14659809 Bug: 16985287 Change-Id: I59ec72fbd40a9b8d28fe548ddad082c03000c045
-rw-r--r--include/media/MediaPlayerInterface.h2
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp16
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp60
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h3
5 files changed, 60 insertions, 23 deletions
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 87717da..cf18a45 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -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
@@ -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;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index c8cb7ed..8eb1269 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -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>
@@ -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;
@@ -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;
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 4fe7075..3b96e88 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -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;
@@ -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;
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();