diff options
author | Andreas Huber <andih@google.com> | 2010-02-09 14:28:32 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-02-09 14:28:32 -0800 |
commit | 4eaef139cf72e8f260ec4cf165c42f579cf6127d (patch) | |
tree | af77cef70e90951ee5889bd014b2875456284f04 /media | |
parent | 88e2a5d3d3b85915eea9a5eddcbe9414bc2976c5 (diff) | |
parent | ffdf4782d43df5fc59808de60c346f1edd695bd9 (diff) | |
download | frameworks_base-4eaef139cf72e8f260ec4cf165c42f579cf6127d.zip frameworks_base-4eaef139cf72e8f260ec4cf165c42f579cf6127d.tar.gz frameworks_base-4eaef139cf72e8f260ec4cf165c42f579cf6127d.tar.bz2 |
Merge "Defer actual work of setDataSource given a URI to the prepare phase in order to not block the calling thread for any significant amount of time..."
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 124 | ||||
-rw-r--r-- | media/libstagefright/include/AwesomePlayer.h | 9 |
2 files changed, 109 insertions, 24 deletions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index c0a2f5b..a13b242 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -111,6 +111,7 @@ private: AwesomePlayer::AwesomePlayer() : mTimeSource(NULL), mAudioPlayer(NULL), + mFlags(0), mLastVideoBuffer(NULL), mVideoBuffer(NULL) { CHECK_EQ(mClient.connect(), OK); @@ -167,23 +168,17 @@ status_t AwesomePlayer::setDataSource( reset_l(); - sp<DataSource> dataSource = DataSource::CreateFromURI(uri, headers); + mUri = uri; - if (dataSource == NULL) { - return UNKNOWN_ERROR; + if (headers) { + mUriHeaders = *headers; } - sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); - - if (extractor == NULL) { - return UNKNOWN_ERROR; - } - - if (dataSource->flags() & DataSource::kWantsPrefetching) { - mPrefetcher = new Prefetcher; - } + // The actual work will be done during preparation in the call to + // ::finishSetDataSource_l to avoid blocking the calling thread in + // setDataSource for any significant time. - return setDataSource_l(extractor); + return OK; } status_t AwesomePlayer::setDataSource( @@ -242,6 +237,10 @@ void AwesomePlayer::reset() { } void AwesomePlayer::reset_l() { + while (mFlags & PREPARING) { + mPreparedCondition.wait(mLock); + } + cancelPlayerEvents(); mVideoRenderer.clear(); @@ -290,6 +289,9 @@ void AwesomePlayer::reset_l() { mSeekTimeUs = 0; mPrefetcher.clear(); + + mUri.setTo(""); + mUriHeaders.clear(); } void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) { @@ -350,6 +352,14 @@ status_t AwesomePlayer::play() { return OK; } + if (!(mFlags & PREPARED)) { + status_t err = prepare_l(); + + if (err != OK) { + return err; + } + } + mFlags |= PLAYING; mFlags |= FIRST_FRAME; @@ -815,30 +825,49 @@ void AwesomePlayer::onCheckAudioStatus() { status_t AwesomePlayer::prepare() { Mutex::Autolock autoLock(mLock); + return prepare_l(); +} +status_t AwesomePlayer::prepare_l() { + if (mFlags & PREPARED) { + return OK; + } + + if (mFlags & PREPARING) { + return UNKNOWN_ERROR; + } + + mIsAsyncPrepare = false; status_t err = prepareAsync_l(); if (err != OK) { return err; } - while (mAsyncPrepareEvent != NULL) { + while (mFlags & PREPARING) { mPreparedCondition.wait(mLock); } - return OK; + return mPrepareResult; } status_t AwesomePlayer::prepareAsync() { Mutex::Autolock autoLock(mLock); + + if (mFlags & PREPARING) { + return UNKNOWN_ERROR; // async prepare already pending + } + + mIsAsyncPrepare = true; return prepareAsync_l(); } status_t AwesomePlayer::prepareAsync_l() { - if (mAsyncPrepareEvent != NULL) { - return UNKNOWN_ERROR; // async prepare already pending. + if (mFlags & PREPARING) { + return UNKNOWN_ERROR; // async prepare already pending } + mFlags |= PREPARING; mAsyncPrepareEvent = new AwesomeEvent( this, &AwesomePlayer::onPrepareAsyncEvent); @@ -847,7 +876,49 @@ status_t AwesomePlayer::prepareAsync_l() { return OK; } +status_t AwesomePlayer::finishSetDataSource_l() { + sp<DataSource> dataSource = + DataSource::CreateFromURI(mUri.string(), &mUriHeaders); + + if (dataSource == NULL) { + return UNKNOWN_ERROR; + } + + sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); + + if (extractor == NULL) { + return UNKNOWN_ERROR; + } + + if (dataSource->flags() & DataSource::kWantsPrefetching) { + mPrefetcher = new Prefetcher; + } + + return setDataSource_l(extractor); +} + void AwesomePlayer::onPrepareAsyncEvent() { + { + Mutex::Autolock autoLock(mLock); + + if (mUri.size() > 0) { + 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(); + + return; + } + } + } + sp<Prefetcher> prefetcher; { @@ -861,16 +932,21 @@ void AwesomePlayer::onPrepareAsyncEvent() { Mutex::Autolock autoLock(mLock); - if (mVideoWidth < 0 || mVideoHeight < 0) { - notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0); - } else { - notifyListener_l(MEDIA_SET_VIDEO_SIZE, mVideoWidth, mVideoHeight); - } + if (mIsAsyncPrepare) { + if (mVideoWidth < 0 || mVideoHeight < 0) { + notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0); + } else { + notifyListener_l(MEDIA_SET_VIDEO_SIZE, mVideoWidth, mVideoHeight); + } - notifyListener_l(MEDIA_PREPARED); + notifyListener_l(MEDIA_PREPARED); + } + mPrepareResult = OK; + mFlags &= ~PREPARING; + mFlags |= PREPARED; mAsyncPrepareEvent = NULL; - mPreparedCondition.signal(); + mPreparedCondition.broadcast(); } } // namespace android diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 651b910..a19784b 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -58,6 +58,7 @@ struct AwesomePlayer { void reset(); status_t prepare(); + status_t prepare_l(); status_t prepareAsync(); status_t prepareAsync_l(); @@ -84,6 +85,8 @@ private: PLAYING = 1, LOOPING = 2, FIRST_FRAME = 4, + PREPARING = 8, + PREPARED = 16, }; mutable Mutex mLock; @@ -97,6 +100,9 @@ private: TimeSource *mTimeSource; + String8 mUri; + KeyedVector<String8, String8> mUriHeaders; + sp<MediaSource> mVideoSource; sp<AwesomeRenderer> mVideoRenderer; @@ -127,6 +133,8 @@ private: sp<TimedEventQueue::Event> mAsyncPrepareEvent; Condition mPreparedCondition; + bool mIsAsyncPrepare; + status_t mPrepareResult; void postVideoEvent_l(int64_t delayUs = -1); void postBufferingEvent_l(); @@ -158,6 +166,7 @@ private: void onBufferingUpdate(); void onCheckAudioStatus(); void onPrepareAsyncEvent(); + status_t finishSetDataSource_l(); AwesomePlayer(const AwesomePlayer &); AwesomePlayer &operator=(const AwesomePlayer &); |