Instead of allocating the decoder instances in response to a call to setDataSource, postpone allocation to the preparation phase where it belongs.
related-to-bug: 2492205
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index ab65b44..5090c39 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -297,13 +297,11 @@
CHECK(meta->findCString(kKeyMIMEType, &mime));
if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
- if (setVideoSource(extractor->getTrack(i)) == OK) {
- haveVideo = true;
- }
+ setVideoSource(extractor->getTrack(i));
+ haveVideo = true;
} else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
- if (setAudioSource(extractor->getTrack(i)) == OK) {
- haveAudio = true;
- }
+ setAudioSource(extractor->getTrack(i));
+ haveAudio = true;
}
if (haveAudio && haveVideo) {
@@ -331,6 +329,9 @@
}
mPrefetcher.clear();
+ mAudioTrack.clear();
+ mVideoTrack.clear();
+
// Shutdown audio first, so that the respone to the reset request
// appears to happen instantaneously as far as the user is concerned
// If we did this later, audio would continue playing while we
@@ -699,32 +700,34 @@
return OK;
}
-status_t AwesomePlayer::setAudioSource(sp<MediaSource> source) {
- if (source == NULL) {
- return UNKNOWN_ERROR;
- }
+void AwesomePlayer::setAudioSource(sp<MediaSource> source) {
+ CHECK(source != NULL);
if (mPrefetcher != NULL) {
source = mPrefetcher->addSource(source);
}
- sp<MetaData> meta = source->getFormat();
+ mAudioTrack = source;
+}
+
+status_t AwesomePlayer::initAudioDecoder() {
+ sp<MetaData> meta = mAudioTrack->getFormat();
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
- mAudioSource = source;
+ mAudioSource = mAudioTrack;
} else {
mAudioSource = OMXCodec::Create(
- mClient.interface(), source->getFormat(),
+ mClient.interface(), mAudioTrack->getFormat(),
false, // createEncoder
- source);
+ mAudioTrack);
}
if (mAudioSource != NULL) {
int64_t durationUs;
- if (source->getFormat()->findInt64(kKeyDuration, &durationUs)) {
+ if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
if (mDurationUs < 0 || durationUs > mDurationUs) {
mDurationUs = durationUs;
}
@@ -734,30 +737,32 @@
return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
}
-status_t AwesomePlayer::setVideoSource(sp<MediaSource> source) {
- if (source == NULL) {
- return UNKNOWN_ERROR;
- }
+void AwesomePlayer::setVideoSource(sp<MediaSource> source) {
+ CHECK(source != NULL);
if (mPrefetcher != NULL) {
source = mPrefetcher->addSource(source);
}
+ mVideoTrack = source;
+}
+
+status_t AwesomePlayer::initVideoDecoder() {
mVideoSource = OMXCodec::Create(
- mClient.interface(), source->getFormat(),
+ mClient.interface(), mVideoTrack->getFormat(),
false, // createEncoder
- source);
+ mVideoTrack);
if (mVideoSource != NULL) {
int64_t durationUs;
- if (source->getFormat()->findInt64(kKeyDuration, &durationUs)) {
+ if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
if (mDurationUs < 0 || durationUs > mDurationUs) {
mDurationUs = durationUs;
}
}
- CHECK(source->getFormat()->findInt32(kKeyWidth, &mVideoWidth));
- CHECK(source->getFormat()->findInt32(kKeyHeight, &mVideoHeight));
+ CHECK(mVideoTrack->getFormat()->findInt32(kKeyWidth, &mVideoWidth));
+ CHECK(mVideoTrack->getFormat()->findInt32(kKeyHeight, &mVideoHeight));
mVideoSource->start();
}
@@ -1045,6 +1050,19 @@
return setDataSource_l(extractor);
}
+void AwesomePlayer::abortPrepare(status_t err) {
+ CHECK(err != OK);
+
+ if (mIsAsyncPrepare) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ }
+
+ mPrepareResult = err;
+ mFlags &= ~PREPARING;
+ mAsyncPrepareEvent = NULL;
+ mPreparedCondition.broadcast();
+}
+
void AwesomePlayer::onPrepareAsyncEvent() {
{
Mutex::Autolock autoLock(mLock);
@@ -1053,15 +1071,7 @@
status_t err = finishSetDataSource_l();
if (err != OK) {
- if (mIsAsyncPrepare) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
- }
-
- mPrepareResult = err;
- mFlags &= ~PREPARING;
- mAsyncPrepareEvent = NULL;
- mPreparedCondition.broadcast();
-
+ abortPrepare(err);
return;
}
}
@@ -1081,6 +1091,24 @@
Mutex::Autolock autoLock(mLock);
+ if (mVideoTrack != NULL && mVideoSource == NULL) {
+ status_t err = initVideoDecoder();
+
+ if (err != OK) {
+ abortPrepare(err);
+ return;
+ }
+ }
+
+ if (mAudioTrack != NULL && mAudioSource == NULL) {
+ status_t err = initAudioDecoder();
+
+ if (err != OK) {
+ abortPrepare(err);
+ return;
+ }
+ }
+
if (mIsAsyncPrepare) {
if (mVideoWidth < 0 || mVideoHeight < 0) {
notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 3590987..7106524 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -112,10 +112,12 @@
sp<DataSource> mFileSource;
+ sp<MediaSource> mVideoTrack;
sp<MediaSource> mVideoSource;
sp<AwesomeRenderer> mVideoRenderer;
bool mVideoRendererIsPreview;
+ sp<MediaSource> mAudioTrack;
sp<MediaSource> mAudioSource;
AudioPlayer *mAudioPlayer;
int64_t mDurationUs;
@@ -199,8 +201,11 @@
void cancelPlayerEvents(bool keepBufferingGoing = false);
- status_t setAudioSource(sp<MediaSource> source);
- status_t setVideoSource(sp<MediaSource> source);
+ void setAudioSource(sp<MediaSource> source);
+ status_t initAudioDecoder();
+
+ void setVideoSource(sp<MediaSource> source);
+ status_t initVideoDecoder();
void onStreamDone();
@@ -210,6 +215,8 @@
void onBufferingUpdate();
void onCheckAudioStatus();
void onPrepareAsyncEvent();
+ void abortPrepare(status_t err);
+
status_t finishSetDataSource_l();
AwesomePlayer(const AwesomePlayer &);