diff options
author | Andreas Huber <andih@google.com> | 2013-02-05 22:46:45 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-02-05 22:46:45 +0000 |
commit | 3c7f8b48fcae6f4b41b66c86008170166e43b428 (patch) | |
tree | f96f734b550e2461f4a67a5a4353792b1c82be75 /media/libmediaplayerservice | |
parent | 198a893671ce80d951625fe328a92073306660d0 (diff) | |
parent | 9575c96b6e418914e2ffc6741ecc8d71e3968dbe (diff) | |
download | frameworks_av-3c7f8b48fcae6f4b41b66c86008170166e43b428.zip frameworks_av-3c7f8b48fcae6f4b41b66c86008170166e43b428.tar.gz frameworks_av-3c7f8b48fcae6f4b41b66c86008170166e43b428.tar.bz2 |
Merge "Support for a "preparation" state that can take care of lengthy"
Diffstat (limited to 'media/libmediaplayerservice')
15 files changed, 406 insertions, 119 deletions
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 450fae5..b04e7a6 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -106,6 +106,26 @@ void NuPlayer::GenericSource::initFromDataSource( NuPlayer::GenericSource::~GenericSource() { } +void NuPlayer::GenericSource::prepareAsync() { + if (mVideoTrack.mSource != NULL) { + sp<MetaData> meta = mVideoTrack.mSource->getFormat(); + + int32_t width, height; + CHECK(meta->findInt32(kKeyWidth, &width)); + CHECK(meta->findInt32(kKeyHeight, &height)); + + notifyVideoSizeChanged(width, height); + } + + notifyFlagsChanged( + FLAG_CAN_PAUSE + | FLAG_CAN_SEEK_BACKWARD + | FLAG_CAN_SEEK_FORWARD + | FLAG_CAN_SEEK); + + notifyPrepared(); +} + void NuPlayer::GenericSource::start() { ALOGI("start"); @@ -262,8 +282,4 @@ void NuPlayer::GenericSource::readBuffer( } } -uint32_t NuPlayer::GenericSource::flags() const { - return FLAG_SEEKABLE; -} - } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index e59ea3a..2da680c 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -42,6 +42,8 @@ struct NuPlayer::GenericSource : public NuPlayer::Source { const sp<AMessage> ¬ify, int fd, int64_t offset, int64_t length); + virtual void prepareAsync(); + virtual void start(); virtual status_t feedMoreTSData(); @@ -51,8 +53,6 @@ struct NuPlayer::GenericSource : public NuPlayer::Source { virtual status_t getDuration(int64_t *durationUs); virtual status_t seekTo(int64_t seekTimeUs); - virtual uint32_t flags() const; - protected: virtual ~GenericSource(); diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index d38ee62..ae67906 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -66,7 +66,7 @@ NuPlayer::HTTPLiveSource::~HTTPLiveSource() { } } -void NuPlayer::HTTPLiveSource::start() { +void NuPlayer::HTTPLiveSource::prepareAsync() { mLiveLooper = new ALooper; mLiveLooper->setName("http live"); mLiveLooper->start(); @@ -81,6 +81,26 @@ void NuPlayer::HTTPLiveSource::start() { mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); mTSParser = new ATSParser; + + notifyVideoSizeChanged(0, 0); + + uint32_t flags = FLAG_CAN_PAUSE; + if (mLiveSession->isSeekable()) { + flags |= FLAG_CAN_SEEK; + flags |= FLAG_CAN_SEEK_BACKWARD; + flags |= FLAG_CAN_SEEK_FORWARD; + } + + if (mLiveSession->hasDynamicDuration()) { + flags |= FLAG_DYNAMIC_DURATION; + } + + notifyFlagsChanged(flags); + + notifyPrepared(); +} + +void NuPlayer::HTTPLiveSource::start() { } sp<MetaData> NuPlayer::HTTPLiveSource::getFormatMeta(bool audio) { @@ -194,18 +214,5 @@ status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) { return OK; } -uint32_t NuPlayer::HTTPLiveSource::flags() const { - uint32_t flags = 0; - if (mLiveSession->isSeekable()) { - flags |= FLAG_SEEKABLE; - } - - if (mLiveSession->hasDynamicDuration()) { - flags |= FLAG_DYNAMIC_DURATION; - } - - return flags; -} - } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h index 4a217af..269f3c0 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h @@ -34,6 +34,7 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { bool uidValid = false, uid_t uid = 0); + virtual void prepareAsync(); virtual void start(); virtual status_t feedMoreTSData(); @@ -43,8 +44,6 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { virtual status_t getDuration(int64_t *durationUs); virtual status_t seekTo(int64_t seekTimeUs); - virtual uint32_t flags() const; - protected: virtual ~HTTPLiveSource(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 0736fbe..78b94ba 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -112,6 +112,7 @@ private: NuPlayer::NuPlayer() : mUIDValid(false), + mSourceFlags(0), mVideoIsAVC(false), mAudioEOS(false), mVideoEOS(false), @@ -142,7 +143,7 @@ void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { mDriver = driver; } -void NuPlayer::setDataSource(const sp<IStreamSource> &source) { +void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) { sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); @@ -174,7 +175,7 @@ static bool IsHTTPLiveURL(const char *url) { return false; } -void NuPlayer::setDataSource( +void NuPlayer::setDataSourceAsync( const char *url, const KeyedVector<String8, String8> *headers) { sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); size_t len = strlen(url); @@ -199,7 +200,7 @@ void NuPlayer::setDataSource( msg->post(); } -void NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) { +void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); @@ -209,6 +210,10 @@ void NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) { msg->post(); } +void NuPlayer::prepareAsync() { + (new AMessage(kWhatPrepare, id()))->post(); +} + void NuPlayer::setVideoSurfaceTextureAsync( const sp<IGraphicBufferProducer> &bufferProducer) { sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id()); @@ -287,6 +292,18 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mSource = static_cast<Source *>(obj.get()); looper()->registerHandler(mSource); + + CHECK(mDriver != NULL); + sp<NuPlayerDriver> driver = mDriver.promote(); + if (driver != NULL) { + driver->notifySetDataSourceCompleted(OK); + } + break; + } + + case kWhatPrepare: + { + mSource->prepareAsync(); break; } @@ -403,9 +420,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { // This is the first time we've found anything playable. - uint32_t flags = mSource->flags(); - - if (flags & Source::FLAG_DYNAMIC_DURATION) { + if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) { schedulePollDuration(); } } @@ -730,7 +745,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatSourceNotify: { - TRESPASS(); // TBD + onSourceNotify(msg); break; } @@ -1233,8 +1248,76 @@ void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) { } } +void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { + int32_t what; + CHECK(msg->findInt32("what", &what)); + + switch (what) { + case Source::kWhatPrepared: + { + sp<NuPlayerDriver> driver = mDriver.promote(); + if (driver != NULL) { + driver->notifyPrepareCompleted(OK); + } + break; + } + + case Source::kWhatFlagsChanged: + { + uint32_t flags; + CHECK(msg->findInt32("flags", (int32_t *)&flags)); + + if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) + && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { + cancelPollDuration(); + } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) + && (flags & Source::FLAG_DYNAMIC_DURATION) + && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { + schedulePollDuration(); + } + + mSourceFlags = flags; + break; + } + + case Source::kWhatVideoSizeChanged: + { + int32_t width, height; + CHECK(msg->findInt32("width", &width)); + CHECK(msg->findInt32("height", &height)); + + notifyListener(MEDIA_SET_VIDEO_SIZE, width, height); + break; + } + + default: + TRESPASS(); + } +} + //////////////////////////////////////////////////////////////////////////////// +void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { + sp<AMessage> notify = dupNotify(); + notify->setInt32("what", kWhatFlagsChanged); + notify->setInt32("flags", flags); + notify->post(); +} + +void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) { + sp<AMessage> notify = dupNotify(); + notify->setInt32("what", kWhatVideoSizeChanged); + notify->setInt32("width", width); + notify->setInt32("height", height); + notify->post(); +} + +void NuPlayer::Source::notifyPrepared() { + sp<AMessage> notify = dupNotify(); + notify->setInt32("what", kWhatPrepared); + notify->post(); +} + void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) { TRESPASS(); } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 0ff6089..50d0462 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -35,12 +35,14 @@ struct NuPlayer : public AHandler { void setDriver(const wp<NuPlayerDriver> &driver); - void setDataSource(const sp<IStreamSource> &source); + void setDataSourceAsync(const sp<IStreamSource> &source); - void setDataSource( + void setDataSourceAsync( const char *url, const KeyedVector<String8, String8> *headers); - void setDataSource(int fd, int64_t offset, int64_t length); + void setDataSourceAsync(int fd, int64_t offset, int64_t length); + + void prepareAsync(); void setVideoSurfaceTextureAsync( const sp<IGraphicBufferProducer> &bufferProducer); @@ -82,6 +84,7 @@ private: enum { kWhatSetDataSource = '=DaS', + kWhatPrepare = 'prep', kWhatSetVideoNativeWindow = '=NaW', kWhatSetAudioSink = '=AuS', kWhatMoreDataQueued = 'more', @@ -102,6 +105,7 @@ private: bool mUIDValid; uid_t mUID; sp<Source> mSource; + uint32_t mSourceFlags; sp<NativeWindowWrapper> mNativeWindow; sp<MediaPlayerBase::AudioSink> mAudioSink; sp<Decoder> mVideoDecoder; @@ -173,6 +177,8 @@ private: void performScanSources(); void performSetSurface(const sp<NativeWindowWrapper> &wrapper); + void onSourceNotify(const sp<AMessage> &msg); + DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 7043404..ab7b4e8 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -21,21 +21,24 @@ #include "NuPlayerDriver.h" #include "NuPlayer.h" +#include "NuPlayerSource.h" #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> +#include <media/stagefright/MetaData.h> namespace android { NuPlayerDriver::NuPlayerDriver() - : mResetInProgress(false), + : mState(STATE_IDLE), + mAsyncResult(UNKNOWN_ERROR), mSetSurfaceInProgress(false), mDurationUs(-1), mPositionUs(-1), mNumFramesTotal(0), mNumFramesDropped(0), mLooper(new ALooper), - mState(UNINITIALIZED), + mPlayerFlags(0), mAtEOS(false), mStartupSeekTimeUs(-1) { mLooper->setName("NuPlayerDriver Looper"); @@ -67,43 +70,76 @@ status_t NuPlayerDriver::setUID(uid_t uid) { status_t NuPlayerDriver::setDataSource( const char *url, const KeyedVector<String8, String8> *headers) { - CHECK_EQ((int)mState, (int)UNINITIALIZED); + Mutex::Autolock autoLock(mLock); - mPlayer->setDataSource(url, headers); + if (mState != STATE_IDLE) { + return INVALID_OPERATION; + } - mState = STOPPED; + mState = STATE_SET_DATASOURCE_PENDING; - return OK; + mPlayer->setDataSourceAsync(url, headers); + + while (mState == STATE_SET_DATASOURCE_PENDING) { + mCondition.wait(mLock); + } + + return mAsyncResult; } status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) { - CHECK_EQ((int)mState, (int)UNINITIALIZED); + Mutex::Autolock autoLock(mLock); - mPlayer->setDataSource(fd, offset, length); + if (mState != STATE_IDLE) { + return INVALID_OPERATION; + } - mState = STOPPED; + mState = STATE_SET_DATASOURCE_PENDING; - return OK; + mPlayer->setDataSourceAsync(fd, offset, length); + + while (mState == STATE_SET_DATASOURCE_PENDING) { + mCondition.wait(mLock); + } + + return mAsyncResult; } status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) { - CHECK_EQ((int)mState, (int)UNINITIALIZED); + Mutex::Autolock autoLock(mLock); - mPlayer->setDataSource(source); + if (mState != STATE_IDLE) { + return INVALID_OPERATION; + } - mState = STOPPED; + mState = STATE_SET_DATASOURCE_PENDING; - return OK; + mPlayer->setDataSourceAsync(source); + + while (mState == STATE_SET_DATASOURCE_PENDING) { + mCondition.wait(mLock); + } + + return mAsyncResult; } status_t NuPlayerDriver::setVideoSurfaceTexture( const sp<IGraphicBufferProducer> &bufferProducer) { Mutex::Autolock autoLock(mLock); - if (mResetInProgress) { + if (mSetSurfaceInProgress) { return INVALID_OPERATION; } + switch (mState) { + case STATE_SET_DATASOURCE_PENDING: + case STATE_RESET_IN_PROGRESS: + return INVALID_OPERATION; + + default: + break; + } + mSetSurfaceInProgress = true; mPlayer->setVideoSurfaceTextureAsync(bufferProducer); @@ -116,23 +152,55 @@ status_t NuPlayerDriver::setVideoSurfaceTexture( } status_t NuPlayerDriver::prepare() { - sendEvent(MEDIA_SET_VIDEO_SIZE, 0, 0); - return OK; + Mutex::Autolock autoLock(mLock); + return prepare_l(); } -status_t NuPlayerDriver::prepareAsync() { - status_t err = prepare(); +status_t NuPlayerDriver::prepare_l() { + switch (mState) { + case STATE_UNPREPARED: + mState = STATE_PREPARING; + mPlayer->prepareAsync(); + while (mState == STATE_PREPARING) { + mCondition.wait(mLock); + } + return (mState == STATE_PREPARED) ? OK : UNKNOWN_ERROR; + default: + return INVALID_OPERATION; + }; +} - notifyListener(MEDIA_PREPARED); +status_t NuPlayerDriver::prepareAsync() { + Mutex::Autolock autoLock(mLock); - return err; + switch (mState) { + case STATE_UNPREPARED: + mState = STATE_PREPARING; + mPlayer->prepareAsync(); + return OK; + default: + return INVALID_OPERATION; + }; } status_t NuPlayerDriver::start() { + Mutex::Autolock autoLock(mLock); + switch (mState) { - case UNINITIALIZED: - return INVALID_OPERATION; - case STOPPED: + case STATE_UNPREPARED: + { + status_t err = prepare_l(); + + if (err != OK) { + return err; + } + + CHECK_EQ(mState, STATE_PREPARED); + + // fall through + } + + case STATE_PREPARED: { mAtEOS = false; mPlayer->start(); @@ -146,21 +214,23 @@ status_t NuPlayerDriver::start() { mStartupSeekTimeUs = -1; } - break; } - case PLAYING: - return OK; - default: - { - CHECK_EQ((int)mState, (int)PAUSED); + case STATE_RUNNING: + break; + + case STATE_PAUSED: + { mPlayer->resume(); break; } + + default: + return INVALID_OPERATION; } - mState = PLAYING; + mState = STATE_RUNNING; return OK; } @@ -170,43 +240,44 @@ status_t NuPlayerDriver::stop() { } status_t NuPlayerDriver::pause() { + Mutex::Autolock autoLock(mLock); + switch (mState) { - case UNINITIALIZED: - return INVALID_OPERATION; - case STOPPED: + case STATE_PAUSED: + case STATE_PREPARED: return OK; - case PLAYING: + + case STATE_RUNNING: mPlayer->pause(); break; + default: - { - CHECK_EQ((int)mState, (int)PAUSED); - return OK; - } + return INVALID_OPERATION; } - mState = PAUSED; + mState = STATE_PAUSED; return OK; } bool NuPlayerDriver::isPlaying() { - return mState == PLAYING && !mAtEOS; + return mState == STATE_RUNNING && !mAtEOS; } status_t NuPlayerDriver::seekTo(int msec) { + Mutex::Autolock autoLock(mLock); + int64_t seekTimeUs = msec * 1000ll; switch (mState) { - case UNINITIALIZED: - return INVALID_OPERATION; - case STOPPED: + case STATE_PREPARED: { mStartupSeekTimeUs = seekTimeUs; break; } - case PLAYING: - case PAUSED: + + case STATE_RUNNING: + case STATE_PAUSED: { mAtEOS = false; mPlayer->seekToAsync(seekTimeUs); @@ -214,8 +285,7 @@ status_t NuPlayerDriver::seekTo(int msec) { } default: - TRESPASS(); - break; + return INVALID_OPERATION; } return OK; @@ -247,17 +317,28 @@ status_t NuPlayerDriver::getDuration(int *msec) { status_t NuPlayerDriver::reset() { Mutex::Autolock autoLock(mLock); - mResetInProgress = true; + switch (mState) { + case STATE_IDLE: + return OK; + + case STATE_SET_DATASOURCE_PENDING: + case STATE_RESET_IN_PROGRESS: + return INVALID_OPERATION; + + default: + break; + } + + mState = STATE_RESET_IN_PROGRESS; mPlayer->resetAsync(); - while (mResetInProgress) { + while (mState == STATE_RESET_IN_PROGRESS) { mCondition.wait(mLock); } mDurationUs = -1; mPositionUs = -1; - mState = UNINITIALIZED; mStartupSeekTimeUs = -1; return OK; @@ -311,20 +392,45 @@ status_t NuPlayerDriver::getParameter(int key, Parcel *reply) { status_t NuPlayerDriver::getMetadata( const media::Metadata::Filter& ids, Parcel *records) { - return INVALID_OPERATION; + Mutex::Autolock autoLock(mLock); + + using media::Metadata; + + Metadata meta(records); + + meta.appendBool( + Metadata::kPauseAvailable, + mPlayerFlags & NuPlayer::Source::FLAG_CAN_PAUSE); + + meta.appendBool( + Metadata::kSeekBackwardAvailable, + mPlayerFlags & NuPlayer::Source::FLAG_CAN_SEEK_BACKWARD); + + meta.appendBool( + Metadata::kSeekForwardAvailable, + mPlayerFlags & NuPlayer::Source::FLAG_CAN_SEEK_FORWARD); + + meta.appendBool( + Metadata::kSeekAvailable, + mPlayerFlags & NuPlayer::Source::FLAG_CAN_SEEK); + + return OK; } void NuPlayerDriver::notifyResetComplete() { Mutex::Autolock autoLock(mLock); - CHECK(mResetInProgress); - mResetInProgress = false; + + CHECK_EQ(mState, STATE_RESET_IN_PROGRESS); + mState = STATE_IDLE; mCondition.broadcast(); } void NuPlayerDriver::notifySetSurfaceComplete() { Mutex::Autolock autoLock(mLock); + CHECK(mSetSurfaceInProgress); mSetSurfaceInProgress = false; + mCondition.broadcast(); } @@ -376,4 +482,37 @@ void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) { sendEvent(msg, ext1, ext2); } +void NuPlayerDriver::notifySetDataSourceCompleted(status_t err) { + Mutex::Autolock autoLock(mLock); + + CHECK_EQ(mState, STATE_SET_DATASOURCE_PENDING); + + mAsyncResult = err; + mState = (err == OK) ? STATE_UNPREPARED : STATE_IDLE; + mCondition.broadcast(); +} + +void NuPlayerDriver::notifyPrepareCompleted(status_t err) { + Mutex::Autolock autoLock(mLock); + + CHECK_EQ(mState, STATE_PREPARING); + + mAsyncResult = err; + + if (err == OK) { + notifyListener(MEDIA_PREPARED); + mState = STATE_PREPARED; + } else { + mState = STATE_UNPREPARED; + } + + mCondition.broadcast(); +} + +void NuPlayerDriver::notifyFlagsChanged(uint32_t flags) { + Mutex::Autolock autoLock(mLock); + + mPlayerFlags = flags; +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h index 553c406..49b8ed2 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h @@ -61,6 +61,8 @@ struct NuPlayerDriver : public MediaPlayerInterface { virtual status_t dump(int fd, const Vector<String16> &args) const; + void notifySetDataSourceCompleted(status_t err); + void notifyPrepareCompleted(status_t err); void notifyResetComplete(); void notifySetSurfaceComplete(); void notifyDuration(int64_t durationUs); @@ -68,17 +70,32 @@ struct NuPlayerDriver : public MediaPlayerInterface { void notifySeekComplete(); void notifyFrameStats(int64_t numFramesTotal, int64_t numFramesDropped); void notifyListener(int msg, int ext1 = 0, int ext2 = 0); + void notifyFlagsChanged(uint32_t flags); protected: virtual ~NuPlayerDriver(); private: + enum State { + STATE_IDLE, + STATE_SET_DATASOURCE_PENDING, + STATE_UNPREPARED, + STATE_PREPARING, + STATE_PREPARED, + STATE_RUNNING, + STATE_PAUSED, + STATE_RESET_IN_PROGRESS, + }; + mutable Mutex mLock; Condition mCondition; + State mState; + + status_t mAsyncResult; + // The following are protected through "mLock" // >>> - bool mResetInProgress; bool mSetSurfaceInProgress; int64_t mDurationUs; int64_t mPositionUs; @@ -88,19 +105,14 @@ private: sp<ALooper> mLooper; sp<NuPlayer> mPlayer; + uint32_t mPlayerFlags; - enum State { - UNINITIALIZED, - STOPPED, - PLAYING, - PAUSED - }; - - State mState; bool mAtEOS; int64_t mStartupSeekTimeUs; + status_t prepare_l(); + DISALLOW_EVIL_CONSTRUCTORS(NuPlayerDriver); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index a3201cf..53c7c12 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -25,11 +25,21 @@ namespace android { struct ABuffer; +struct MetaData; struct NuPlayer::Source : public AHandler { enum Flags { - FLAG_SEEKABLE = 1, - FLAG_DYNAMIC_DURATION = 2, + FLAG_CAN_PAUSE = 1, + FLAG_CAN_SEEK_BACKWARD = 2, // the "10 sec back button" + FLAG_CAN_SEEK_FORWARD = 4, // the "10 sec forward button" + FLAG_CAN_SEEK = 8, // the "seek bar" + FLAG_DYNAMIC_DURATION = 16, + }; + + enum { + kWhatPrepared, + kWhatFlagsChanged, + kWhatVideoSizeChanged, }; // The provides message is used to notify the player about various @@ -38,6 +48,8 @@ struct NuPlayer::Source : public AHandler { : mNotify(notify) { } + virtual void prepareAsync() = 0; + virtual void start() = 0; virtual void stop() {} @@ -58,8 +70,6 @@ struct NuPlayer::Source : public AHandler { return INVALID_OPERATION; } - virtual uint32_t flags() const = 0; - protected: virtual ~Source() {} @@ -69,6 +79,10 @@ protected: sp<AMessage> dupNotify() const { return mNotify->dup(); } + void notifyFlagsChanged(uint32_t flags); + void notifyVideoSizeChanged(int32_t width, int32_t height); + void notifyPrepared(); + private: sp<AMessage> mNotify; diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index 3035589..e4d72d9 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -65,7 +65,7 @@ NuPlayer::RTSPSource::~RTSPSource() { mLooper->stop(); } -void NuPlayer::RTSPSource::start() { +void NuPlayer::RTSPSource::prepareAsync() { if (mLooper == NULL) { mLooper = new ALooper; mLooper->setName("rtsp"); @@ -88,13 +88,27 @@ void NuPlayer::RTSPSource::start() { (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0, mUIDValid, mUID); - mSDPLoader->load(mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); + mSDPLoader->load( + mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); } else { mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID); mLooper->registerHandler(mHandler); mHandler->connect(); } + + notifyVideoSizeChanged(0, 0); + + notifyFlagsChanged( + FLAG_CAN_PAUSE + | FLAG_CAN_SEEK_BACKWARD + | FLAG_CAN_SEEK_FORWARD + | FLAG_CAN_SEEK); + + notifyPrepared(); +} + +void NuPlayer::RTSPSource::start() { } void NuPlayer::RTSPSource::stop() { @@ -225,10 +239,6 @@ void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { mHandler->seek(seekTimeUs); } -uint32_t NuPlayer::RTSPSource::flags() const { - return FLAG_SEEKABLE; -} - void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { if (msg->what() == kWhatDisconnect) { uint32_t replyID; diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index b2a7dae..cbb6f90 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -40,6 +40,7 @@ struct NuPlayer::RTSPSource : public NuPlayer::Source { uid_t uid = 0, bool isSDP = false); + virtual void prepareAsync(); virtual void start(); virtual void stop(); @@ -50,8 +51,6 @@ struct NuPlayer::RTSPSource : public NuPlayer::Source { virtual status_t getDuration(int64_t *durationUs); virtual status_t seekTo(int64_t seekTimeUs); - virtual uint32_t flags() const; - void onMessageReceived(const sp<AMessage> &msg); protected: diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp index 9b04833..df03f86 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp @@ -43,6 +43,12 @@ NuPlayer::StreamingSource::StreamingSource( NuPlayer::StreamingSource::~StreamingSource() { } +void NuPlayer::StreamingSource::prepareAsync() { + notifyVideoSizeChanged(0, 0); + notifyFlagsChanged(0); + notifyPrepared(); +} + void NuPlayer::StreamingSource::start() { mStreamListener = new NuPlayerStreamListener(mSource, 0); @@ -176,9 +182,5 @@ status_t NuPlayer::StreamingSource::dequeueAccessUnit( return err; } -uint32_t NuPlayer::StreamingSource::flags() const { - return 0; -} - } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.h b/media/libmediaplayerservice/nuplayer/StreamingSource.h index dc616f7..80b061c 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.h +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.h @@ -31,14 +31,13 @@ struct NuPlayer::StreamingSource : public NuPlayer::Source { const sp<AMessage> ¬ify, const sp<IStreamSource> &source); + virtual void prepareAsync(); virtual void start(); virtual status_t feedMoreTSData(); virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit); - virtual uint32_t flags() const; - protected: virtual ~StreamingSource(); diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp index d659b73..d31d947 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp +++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp @@ -117,6 +117,12 @@ MP4Source::MP4Source( MP4Source::~MP4Source() { } +void MP4Source::prepareAsync() { + notifyVideoSizeChanged(0, 0); + notifyFlagsChanged(0); + notifyPrepared(); +} + void MP4Source::start() { mLooper->start(false /* runOnCallingThread */); mParser->start(new StreamSource(mSource)); @@ -135,8 +141,4 @@ status_t MP4Source::dequeueAccessUnit( return mParser->dequeueAccessUnit(audio, accessUnit); } -uint32_t MP4Source::flags() const { - return 0; -} - } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h index b16a111..a6ef622 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h +++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h @@ -26,6 +26,7 @@ struct FragmentedMP4Parser; struct MP4Source : public NuPlayer::Source { MP4Source(const sp<AMessage> ¬ify, const sp<IStreamSource> &source); + virtual void prepareAsync(); virtual void start(); virtual status_t feedMoreTSData(); @@ -35,8 +36,6 @@ struct MP4Source : public NuPlayer::Source { virtual status_t dequeueAccessUnit( bool audio, sp<ABuffer> *accessUnit); - virtual uint32_t flags() const; - protected: virtual ~MP4Source(); |