summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-02-11 13:09:36 -0800
committerAndreas Huber <andih@google.com>2011-02-11 13:09:36 -0800
commitf03034408506051f2f836e59305fcd5f662bf19a (patch)
tree867619a9b721eb07d8c13e08966ca2b1f4689631 /media/libstagefright
parentd52e5c3edcb1aedce8b5bea705422fd47b06622e (diff)
downloadframeworks_av-f03034408506051f2f836e59305fcd5f662bf19a.zip
frameworks_av-f03034408506051f2f836e59305fcd5f662bf19a.tar.gz
frameworks_av-f03034408506051f2f836e59305fcd5f662bf19a.tar.bz2
Start playing (and decoding) audio only after the first video frame has been decoded.
if there's both audio and video content. This gives the video decoder an opportunity to fill its internal buffer queue at the start of playback. Change-Id: Ib2c95753b430e4e47207953b913b607024a328d7 related-to-bug: 3431702
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/AwesomePlayer.cpp87
-rw-r--r--media/libstagefright/include/AwesomePlayer.h5
2 files changed, 68 insertions, 24 deletions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 8963951..e368848 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -794,34 +794,33 @@ status_t AwesomePlayer::play_l() {
mAudioPlayer = new AudioPlayer(mAudioSink, this);
mAudioPlayer->setSource(mAudioSource);
- // We've already started the MediaSource in order to enable
- // the prefetcher to read its data.
- status_t err = mAudioPlayer->start(
- true /* sourceAlreadyStarted */);
+ mTimeSource = mAudioPlayer;
- if (err != OK) {
- delete mAudioPlayer;
- mAudioPlayer = NULL;
+ deferredAudioSeek = true;
- mFlags &= ~(PLAYING | FIRST_FRAME);
+ mWatchForAudioSeekComplete = false;
+ mWatchForAudioEOS = true;
+ }
+ }
- if (mDecryptHandle != NULL) {
- mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
- Playback::STOP, 0);
- }
+ CHECK(!(mFlags & AUDIO_RUNNING));
- return err;
- }
+ if (mVideoSource == NULL) {
+ status_t err = startAudioPlayer_l();
- mTimeSource = mAudioPlayer;
+ if (err != OK) {
+ delete mAudioPlayer;
+ mAudioPlayer = NULL;
- deferredAudioSeek = true;
+ mFlags &= ~(PLAYING | FIRST_FRAME);
- mWatchForAudioSeekComplete = false;
- mWatchForAudioEOS = true;
+ if (mDecryptHandle != NULL) {
+ mDrmManagerClient->setPlaybackStatus(
+ mDecryptHandle, Playback::STOP, 0);
+ }
+
+ return err;
}
- } else {
- mAudioPlayer->resume();
}
}
@@ -853,6 +852,36 @@ status_t AwesomePlayer::play_l() {
return OK;
}
+status_t AwesomePlayer::startAudioPlayer_l() {
+ CHECK(!(mFlags & AUDIO_RUNNING));
+
+ if (mAudioSource == NULL || mAudioPlayer == NULL) {
+ return OK;
+ }
+
+ if (!(mFlags & AUDIOPLAYER_STARTED)) {
+ mFlags |= AUDIOPLAYER_STARTED;
+
+ // We've already started the MediaSource in order to enable
+ // the prefetcher to read its data.
+ status_t err = mAudioPlayer->start(
+ true /* sourceAlreadyStarted */);
+
+ if (err != OK) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ return err;
+ }
+ } else {
+ mAudioPlayer->resume();
+ }
+
+ mFlags |= AUDIO_RUNNING;
+
+ mWatchForAudioEOS = true;
+
+ return OK;
+}
+
void AwesomePlayer::notifyVideoSize_l() {
sp<MetaData> meta = mVideoSource->getFormat();
@@ -954,7 +983,7 @@ status_t AwesomePlayer::pause_l(bool at_eos) {
cancelPlayerEvents(true /* keepBufferingGoing */);
- if (mAudioPlayer != NULL) {
+ if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
if (at_eos) {
// If we played the audio stream to completion we
// want to make sure that all samples remaining in the audio
@@ -963,6 +992,8 @@ status_t AwesomePlayer::pause_l(bool at_eos) {
} else {
mAudioPlayer->pause();
}
+
+ mFlags &= ~AUDIO_RUNNING;
}
mFlags &= ~PLAYING;
@@ -1195,9 +1226,7 @@ void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
// requested seek time instead.
mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
- mAudioPlayer->resume();
mWatchForAudioSeekComplete = true;
- mWatchForAudioEOS = true;
} else if (!mSeekNotificationSent) {
// If we're playing video only, report seek complete now,
// otherwise audio player will notify us later.
@@ -1241,8 +1270,10 @@ void AwesomePlayer::onVideoEvent() {
// locations, we'll "pause" the audio source, causing it to
// stop reading input data until a subsequent seek.
- if (mAudioPlayer != NULL) {
+ if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
mAudioPlayer->pause();
+
+ mFlags &= ~AUDIO_RUNNING;
}
mAudioSource->pause();
}
@@ -1312,6 +1343,14 @@ void AwesomePlayer::onVideoEvent() {
bool wasSeeking = mSeeking;
finishSeekIfNecessary(timeUs);
+ if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
+ status_t err = startAudioPlayer_l();
+ if (err != OK) {
+ LOGE("Startung the audio player failed w/ err %d", err);
+ return;
+ }
+ }
+
TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
if (mFlags & FIRST_FRAME) {
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 5120a12..797e5ca 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -121,6 +121,9 @@ private:
// We're triggering a single video event to display the first frame
// after the seekpoint.
SEEK_PREVIEW = 4096,
+
+ AUDIO_RUNNING = 8192,
+ AUDIOPLAYER_STARTED = 16384,
};
mutable Mutex mLock;
@@ -256,6 +259,8 @@ private:
void finishSeekIfNecessary(int64_t videoTimeUs);
void ensureCacheIsFetching_l();
+ status_t startAudioPlayer_l();
+
AwesomePlayer(const AwesomePlayer &);
AwesomePlayer &operator=(const AwesomePlayer &);
};