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 &);