summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-03-22 10:31:21 -0700
committerAndreas Huber <andih@google.com>2011-03-22 13:18:09 -0700
commit84b343f29063fbfa2ee61b2e3d37ba059ca507d4 (patch)
treeb1bb4c481a3348b4ca480f262b7016e45106f8e5 /media
parent0b500c2e81288190a6ce8b20c842a83a19e038b5 (diff)
downloadframeworks_av-84b343f29063fbfa2ee61b2e3d37ba059ca507d4.zip
frameworks_av-84b343f29063fbfa2ee61b2e3d37ba059ca507d4.tar.gz
frameworks_av-84b343f29063fbfa2ee61b2e3d37ba059ca507d4.tar.bz2
Delay signaling the end of audio playback until all frames have actually played.
Change-Id: I1fa07358a885a818fd0a5d7da425740f86095e10 related-to-bug: 3404000
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/AudioPlayer.cpp49
-rw-r--r--media/libstagefright/AwesomePlayer.cpp10
-rw-r--r--media/libstagefright/include/AwesomePlayer.h4
3 files changed, 55 insertions, 8 deletions
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index e7c0299..07f250a 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -280,6 +280,26 @@ void AudioPlayer::AudioCallback(int event, void *info) {
buffer->size = numBytesWritten;
}
+uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
+ uint32_t numFramesPlayedOut;
+ status_t err;
+
+ if (mAudioSink != NULL) {
+ err = mAudioSink->getPosition(&numFramesPlayedOut);
+ } else {
+ err = mAudioTrack->getPosition(&numFramesPlayedOut);
+ }
+
+ if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
+ return 0;
+ }
+
+ // mNumFramesPlayed is the number of frames submitted
+ // to the audio sink for playback, but not all of them
+ // may have played out by now.
+ return mNumFramesPlayed - numFramesPlayedOut;
+}
+
size_t AudioPlayer::fillBuffer(void *data, size_t size) {
if (mNumFramesPlayed == 0) {
LOGV("AudioCallback");
@@ -342,7 +362,34 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
if (err != OK) {
if (mObserver && !mReachedEOS) {
- mObserver->postAudioEOS();
+ // We don't want to post EOS right away but only
+ // after all frames have actually been played out.
+
+ // These are the number of frames submitted to the
+ // AudioTrack that you haven't heard yet.
+ uint32_t numFramesPendingPlayout =
+ getNumFramesPendingPlayout();
+
+ // These are the number of frames we're going to
+ // submit to the AudioTrack by returning from this
+ // callback.
+ uint32_t numAdditionalFrames = size_done / mFrameSize;
+
+ numFramesPendingPlayout += numAdditionalFrames;
+
+ int64_t timeToCompletionUs =
+ (1000000ll * numFramesPendingPlayout) / mSampleRate;
+
+ LOGV("total number of frames played: %lld (%lld us)",
+ (mNumFramesPlayed + numAdditionalFrames),
+ 1000000ll * (mNumFramesPlayed + numAdditionalFrames)
+ / mSampleRate);
+
+ LOGV("%d frames left to play, %lld us (%.2f secs)",
+ numFramesPendingPlayout,
+ timeToCompletionUs, timeToCompletionUs / 1E6);
+
+ mObserver->postAudioEOS(timeToCompletionUs + mLatencyUs);
}
mReachedEOS = true;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 35bc0b8..7fdb1a1 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1513,12 +1513,12 @@ void AwesomePlayer::postVideoLagEvent_l() {
mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
}
-void AwesomePlayer::postCheckAudioStatusEvent_l() {
+void AwesomePlayer::postCheckAudioStatusEvent_l(int64_t delayUs) {
if (mAudioStatusEventPending) {
return;
}
mAudioStatusEventPending = true;
- mQueue.postEvent(mCheckAudioStatusEvent);
+ mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
}
void AwesomePlayer::onCheckAudioStatus() {
@@ -1810,12 +1810,12 @@ uint32_t AwesomePlayer::flags() const {
return mExtractorFlags;
}
-void AwesomePlayer::postAudioEOS() {
- postCheckAudioStatusEvent_l();
+void AwesomePlayer::postAudioEOS(int64_t delayUs) {
+ postCheckAudioStatusEvent_l(delayUs);
}
void AwesomePlayer::postAudioSeekComplete() {
- postCheckAudioStatusEvent_l();
+ postCheckAudioStatusEvent_l(0 /* delayUs */);
}
} // namespace android
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index b26f202..a9b7ae8 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -93,7 +93,7 @@ struct AwesomePlayer {
// This is a mask of MediaExtractor::Flags.
uint32_t flags() const;
- void postAudioEOS();
+ void postAudioEOS(int64_t delayUs = 0ll);
void postAudioSeekComplete();
private:
@@ -203,7 +203,7 @@ private:
void postVideoEvent_l(int64_t delayUs = -1);
void postBufferingEvent_l();
void postStreamDoneEvent_l(status_t status);
- void postCheckAudioStatusEvent_l();
+ void postCheckAudioStatusEvent_l(int64_t delayUs);
void postVideoLagEvent_l();
status_t play_l();