diff options
author | Andreas Huber <andih@google.com> | 2012-02-28 15:54:51 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2012-02-28 15:54:51 -0800 |
commit | 4484bdd2f99a753b0801f0c13ca8a2b7bc38695a (patch) | |
tree | 8340a689fd485b4ae2fa0fa394d7f1b027890cfd /media | |
parent | f64dfccd96286255fd382486c94cdb48921c45fa (diff) | |
download | frameworks_base-4484bdd2f99a753b0801f0c13ca8a2b7bc38695a.zip frameworks_base-4484bdd2f99a753b0801f0c13ca8a2b7bc38695a.tar.gz frameworks_base-4484bdd2f99a753b0801f0c13ca8a2b7bc38695a.tar.bz2 |
Separate the notion of "stop" from that of "release", i.e.
stop - means transition back to LOADED state and keeping the component
instance allocated.
release - means we get rid of the component completely.
Change-Id: I40ad01ce70821faaad43f57999249904f9144924
Diffstat (limited to 'media')
-rw-r--r-- | media/jni/android_media_MediaCodec.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 194 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 46 |
3 files changed, 187 insertions, 55 deletions
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 675339e..71e698f 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -84,7 +84,7 @@ status_t JMediaCodec::initCheck() const { } JMediaCodec::~JMediaCodec() { - mCodec->stop(); + mCodec->release(); JNIEnv *env = AndroidRuntime::getJNIEnv(); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 85bd7ba..9a9d094 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -165,18 +165,36 @@ struct ACodec::UninitializedState : public ACodec::BaseState { protected: virtual bool onMessageReceived(const sp<AMessage> &msg); + virtual void stateEntered(); private: void onSetup(const sp<AMessage> &msg); - void onAllocateComponent(const sp<AMessage> &msg); - void onConfigureComponent(const sp<AMessage> &msg); - void onStart(); + bool onAllocateComponent(const sp<AMessage> &msg); DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); }; //////////////////////////////////////////////////////////////////////////////// +struct ACodec::LoadedState : public ACodec::BaseState { + LoadedState(ACodec *codec); + +protected: + virtual bool onMessageReceived(const sp<AMessage> &msg); + virtual void stateEntered(); + +private: + friend struct ACodec::UninitializedState; + + bool onConfigureComponent(const sp<AMessage> &msg); + void onStart(); + void onShutdown(bool keepComponentAllocated); + + DISALLOW_EVIL_CONSTRUCTORS(LoadedState); +}; + +//////////////////////////////////////////////////////////////////////////////// + struct ACodec::LoadedToIdleState : public ACodec::BaseState { LoadedToIdleState(ACodec *codec); @@ -312,8 +330,10 @@ private: ACodec::ACodec() : mNode(NULL), mSentFormat(false), - mIsEncoder(false) { + mIsEncoder(false), + mShutdownInProgress(false) { mUninitializedState = new UninitializedState(this); + mLoadedState = new LoadedState(this); mLoadedToIdleState = new LoadedToIdleState(this); mIdleToExecutingState = new IdleToExecutingState(this); mExecutingState = new ExecutingState(this); @@ -369,8 +389,10 @@ void ACodec::signalResume() { (new AMessage(kWhatResume, id()))->post(); } -void ACodec::initiateShutdown() { - (new AMessage(kWhatShutdown, id()))->post(); +void ACodec::initiateShutdown(bool keepComponentAllocated) { + sp<AMessage> msg = new AMessage(kWhatShutdown, id()); + msg->setInt32("keepComponentAllocated", keepComponentAllocated); + msg->post(); } status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { @@ -2492,6 +2514,10 @@ ACodec::UninitializedState::UninitializedState(ACodec *codec) : BaseState(codec) { } +void ACodec::UninitializedState::stateEntered() { + ALOGV("Now uninitialized"); +} + bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { bool handled = false; @@ -2511,22 +2537,13 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { break; } - case ACodec::kWhatConfigureComponent: - { - onConfigureComponent(msg); - handled = true; - break; - } - - case ACodec::kWhatStart: - { - onStart(); - handled = true; - break; - } - case ACodec::kWhatShutdown: { + int32_t keepComponentAllocated; + CHECK(msg->findInt32( + "keepComponentAllocated", &keepComponentAllocated)); + CHECK(!keepComponentAllocated); + sp<AMessage> notify = mCodec->mNotify->dup(); notify->setInt32("what", ACodec::kWhatShutdownCompleted); notify->post(); @@ -2554,22 +2571,16 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { void ACodec::UninitializedState::onSetup( const sp<AMessage> &msg) { - onAllocateComponent(msg); - onConfigureComponent(msg); - onStart(); + if (onAllocateComponent(msg) + && mCodec->mLoadedState->onConfigureComponent(msg)) { + mCodec->mLoadedState->onStart(); + } } -void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { +bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { ALOGV("onAllocateComponent"); - if (mCodec->mNode != NULL) { - CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); - - mCodec->mNativeWindow.clear(); - mCodec->mNode = NULL; - mCodec->mOMX.clear(); - mCodec->mComponentName.clear(); - } + CHECK(mCodec->mNode == NULL); OMXClient client; CHECK_EQ(client.connect(), (status_t)OK); @@ -2628,7 +2639,7 @@ void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { } mCodec->signalError(OMX_ErrorComponentNotFound); - return; + return false; } sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id()); @@ -2649,9 +2660,96 @@ void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { notify->setString("componentName", mCodec->mComponentName.c_str()); notify->post(); } + + mCodec->changeState(mCodec->mLoadedState); + + return true; } -void ACodec::UninitializedState::onConfigureComponent( +//////////////////////////////////////////////////////////////////////////////// + +ACodec::LoadedState::LoadedState(ACodec *codec) + : BaseState(codec) { +} + +void ACodec::LoadedState::stateEntered() { + ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); + + if (mCodec->mShutdownInProgress) { + bool keepComponentAllocated = mCodec->mKeepComponentAllocated; + + mCodec->mShutdownInProgress = false; + mCodec->mKeepComponentAllocated = false; + + onShutdown(keepComponentAllocated); + } +} + +void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { + if (!keepComponentAllocated) { + CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); + + mCodec->mNativeWindow.clear(); + mCodec->mNode = NULL; + mCodec->mOMX.clear(); + mCodec->mComponentName.clear(); + + mCodec->changeState(mCodec->mUninitializedState); + } + + sp<AMessage> notify = mCodec->mNotify->dup(); + notify->setInt32("what", ACodec::kWhatShutdownCompleted); + notify->post(); +} + +bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { + bool handled = false; + + switch (msg->what()) { + case ACodec::kWhatConfigureComponent: + { + onConfigureComponent(msg); + handled = true; + break; + } + + case ACodec::kWhatStart: + { + onStart(); + handled = true; + break; + } + + case ACodec::kWhatShutdown: + { + int32_t keepComponentAllocated; + CHECK(msg->findInt32( + "keepComponentAllocated", &keepComponentAllocated)); + + onShutdown(keepComponentAllocated); + + handled = true; + break; + } + + case ACodec::kWhatFlush: + { + sp<AMessage> notify = mCodec->mNotify->dup(); + notify->setInt32("what", ACodec::kWhatFlushCompleted); + notify->post(); + + handled = true; + break; + } + + default: + return BaseState::onMessageReceived(msg); + } + + return handled; +} + +bool ACodec::LoadedState::onConfigureComponent( const sp<AMessage> &msg) { ALOGV("onConfigureComponent"); @@ -2664,7 +2762,7 @@ void ACodec::UninitializedState::onConfigureComponent( if (err != OK) { mCodec->signalError(OMX_ErrorUndefined, err); - return; + return false; } sp<RefBase> obj; @@ -2682,9 +2780,11 @@ void ACodec::UninitializedState::onConfigureComponent( notify->setInt32("what", ACodec::kWhatComponentConfigured); notify->post(); } + + return true; } -void ACodec::UninitializedState::onStart() { +void ACodec::LoadedState::onStart() { ALOGV("onStart"); CHECK_EQ(mCodec->mOMX->sendCommand( @@ -2873,6 +2973,13 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatShutdown: { + int32_t keepComponentAllocated; + CHECK(msg->findInt32( + "keepComponentAllocated", &keepComponentAllocated)); + + mCodec->mShutdownInProgress = true; + mCodec->mKeepComponentAllocated = keepComponentAllocated; + mActive = false; CHECK_EQ(mCodec->mOMX->sendCommand( @@ -3210,20 +3317,7 @@ bool ACodec::IdleToLoadedState::onOMXEvent( CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded); - ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); - - CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); - - mCodec->mNativeWindow.clear(); - mCodec->mNode = NULL; - mCodec->mOMX.clear(); - mCodec->mComponentName.clear(); - - mCodec->changeState(mCodec->mUninitializedState); - - sp<AMessage> notify = mCodec->mNotify->dup(); - notify->setInt32("what", ACodec::kWhatShutdownCompleted); - notify->post(); + mCodec->changeState(mCodec->mLoadedState); return true; } diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index e14b1c4..a9e7f360 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -164,6 +164,13 @@ status_t MediaCodec::stop() { return PostAndAwaitResponse(msg, &response); } +status_t MediaCodec::release() { + sp<AMessage> msg = new AMessage(kWhatRelease, id()); + + sp<AMessage> response; + return PostAndAwaitResponse(msg, &response); +} + status_t MediaCodec::queueInputBuffer( size_t index, size_t offset, @@ -422,6 +429,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } case STOPPING: + case RELEASING: { // Ignore the error, assuming we'll still get // the shutdown complete notification. @@ -577,7 +585,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { { /* size_t index = */updateBuffers(kPortIndexInput, msg); - if (mState == FLUSHING || mState == STOPPING) { + if (mState == FLUSHING + || mState == STOPPING + || mState == RELEASING) { returnBuffersToCodecOnPort(kPortIndexInput); break; } @@ -596,7 +606,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { { /* size_t index = */updateBuffers(kPortIndexOutput, msg); - if (mState == FLUSHING || mState == STOPPING) { + if (mState == FLUSHING + || mState == STOPPING + || mState == RELEASING) { returnBuffersToCodecOnPort(kPortIndexOutput); break; } @@ -628,8 +640,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case ACodec::kWhatShutdownCompleted: { - CHECK_EQ(mState, STOPPING); - setState(UNINITIALIZED); + if (mState == STOPPING) { + setState(INITIALIZED); + } else { + CHECK_EQ(mState, RELEASING); + setState(UNINITIALIZED); + } (new AMessage)->postReply(mReplyID); break; @@ -767,6 +783,28 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mReplyID = replyID; setState(STOPPING); + mCodec->initiateShutdown(true /* keepComponentAllocated */); + returnBuffersToCodec(); + break; + } + + case kWhatRelease: + { + uint32_t replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + + if (mState != INITIALIZED + && mState != CONFIGURED && mState != STARTED) { + sp<AMessage> response = new AMessage; + response->setInt32("err", INVALID_OPERATION); + + response->postReply(replyID); + break; + } + + mReplyID = replyID; + setState(RELEASING); + mCodec->initiateShutdown(); returnBuffersToCodec(); break; |