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 | c95c2ddcdfc974f42408a377fbe2de51b94a8c94 (patch) | |
tree | 24239ca3f0d24f790b73d92627de057f738f91d5 | |
parent | a3873833d518e032138cf70188b6f33cd7acec3d (diff) | |
download | frameworks_av-c95c2ddcdfc974f42408a377fbe2de51b94a8c94.zip frameworks_av-c95c2ddcdfc974f42408a377fbe2de51b94a8c94.tar.gz frameworks_av-c95c2ddcdfc974f42408a377fbe2de51b94a8c94.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
-rw-r--r-- | cmds/stagefright/SimplePlayer.cpp | 2 | ||||
-rw-r--r-- | cmds/stagefright/codec.cpp | 2 | ||||
-rw-r--r-- | include/media/stagefright/ACodec.h | 10 | ||||
-rw-r--r-- | include/media/stagefright/MediaCodec.h | 9 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 194 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 46 |
6 files changed, 206 insertions, 57 deletions
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp index f269e80..fac3a8c 100644 --- a/cmds/stagefright/SimplePlayer.cpp +++ b/cmds/stagefright/SimplePlayer.cpp @@ -396,7 +396,7 @@ status_t SimplePlayer::onReset() { for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { CodecState *state = &mStateByTrackIndex.editValueAt(i); - CHECK_EQ(state->mCodec->stop(), (status_t)OK); + CHECK_EQ(state->mCodec->release(), (status_t)OK); } mStartTimeRealUs = -1ll; diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp index b850190..fbf800c 100644 --- a/cmds/stagefright/codec.cpp +++ b/cmds/stagefright/codec.cpp @@ -295,7 +295,7 @@ static int decode( for (size_t i = 0; i < stateByTrack.size(); ++i) { CodecState *state = &stateByTrack.editValueAt(i); - CHECK_EQ((status_t)OK, state->mCodec->stop()); + CHECK_EQ((status_t)OK, state->mCodec->release()); } return 0; diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 70799a6..6735aff 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -49,7 +49,7 @@ struct ACodec : public AHierarchicalStateMachine { void initiateSetup(const sp<AMessage> &msg); void signalFlush(); void signalResume(); - void initiateShutdown(); + void initiateShutdown(bool keepComponentAllocated = false); void initiateAllocateComponent(const sp<AMessage> &msg); void initiateConfigureComponent(const sp<AMessage> &msg); @@ -61,6 +61,7 @@ protected: private: struct BaseState; struct UninitializedState; + struct LoadedState; struct LoadedToIdleState; struct IdleToExecutingState; struct ExecutingState; @@ -107,6 +108,7 @@ private: sp<AMessage> mNotify; sp<UninitializedState> mUninitializedState; + sp<LoadedState> mLoadedState; sp<LoadedToIdleState> mLoadedToIdleState; sp<IdleToExecutingState> mIdleToExecutingState; sp<ExecutingState> mExecutingState; @@ -131,6 +133,12 @@ private: bool mSentFormat; bool mIsEncoder; + bool mShutdownInProgress; + + // If "mKeepComponentAllocated" we only transition back to Loaded state + // and do not release the component instance. + bool mKeepComponentAllocated; + status_t allocateBuffersOnPort(OMX_U32 portIndex); status_t freeBuffersOnPort(OMX_U32 portIndex); status_t freeBuffer(OMX_U32 portIndex, size_t i); diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index 8c11c9c..72ac56a 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -53,8 +53,15 @@ struct MediaCodec : public AHandler { uint32_t flags); status_t start(); + + // Returns to a state in which the component remains allocated but + // unconfigured. status_t stop(); + // Client MUST call release before releasing final reference to this + // object. + status_t release(); + status_t flush(); status_t queueInputBuffer( @@ -97,6 +104,7 @@ private: STARTED, FLUSHING, STOPPING, + RELEASING, }; enum { @@ -109,6 +117,7 @@ private: kWhatConfigure = 'conf', kWhatStart = 'strt', kWhatStop = 'stop', + kWhatRelease = 'rele', kWhatDequeueInputBuffer = 'deqI', kWhatQueueInputBuffer = 'queI', kWhatDequeueOutputBuffer = 'deqO', 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..a9e7f36 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; |