Loading media/libstagefright/ACodec.cpp +71 −12 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ protected: virtual PortMode getPortMode(OMX_U32 portIndex); virtual void stateExited(); virtual bool onMessageReceived(const sp<AMessage> &msg); virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); Loading Loading @@ -553,6 +554,7 @@ ACodec::ACodec() mTunneled(false), mDescribeColorAspectsIndex((OMX_INDEXTYPE)0), mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0), mStateGeneration(0), mVendorExtensionsStatus(kExtensionsUnchecked) { mUninitializedState = new UninitializedState(this); mLoadedState = new LoadedState(this); Loading Loading @@ -5322,6 +5324,10 @@ ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( return KEEP_BUFFERS; } void ACodec::BaseState::stateExited() { ++mCodec->mStateGeneration; } bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatInputBufferFilled: Loading Loading @@ -5398,6 +5404,12 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { break; } case ACodec::kWhatForceStateTransition: { ALOGV("Already transitioned --- ignore"); break; } default: return false; } Loading Loading @@ -6988,7 +7000,6 @@ void ACodec::ExecutingState::resume() { void ACodec::ExecutingState::stateEntered() { ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); mCodec->processDeferredMessages(); } Loading Loading @@ -7614,6 +7625,30 @@ void ACodec::onSignalEndOfInputStream() { mCallback->onSignaledInputEOS(err); } void ACodec::forceStateTransition(int generation) { if (generation != mStateGeneration) { ALOGV("Ignoring stale force state transition message: #%d (now #%d)", generation, mStateGeneration); return; } ALOGE("State machine stuck"); // Error must have already been signalled to the client. // Deferred messages will be handled at LoadedState at the end of the // transition. mShutdownInProgress = true; // No shutdown complete callback at the end of the transition. mExplicitShutdown = false; mKeepComponentAllocated = true; status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); if (err != OK) { // TODO: do some recovery here. } else { changeState(mExecutingToIdleState); } } bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { mCodec->onFrameRendered(mediaTimeUs, systemNano); return true; Loading Loading @@ -7680,7 +7715,14 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( switch (msg->what()) { case kWhatFlush: case kWhatShutdown: case kWhatShutdown: { if (mCodec->mFatalError) { sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); msg->setInt32("generation", mCodec->mStateGeneration); msg->post(3000000); } // fall-through } case kWhatResume: case kWhatSetParameters: { Loading @@ -7693,6 +7735,16 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( break; } case kWhatForceStateTransition: { int32_t generation = 0; CHECK(msg->findInt32("generation", &generation)); mCodec->forceStateTransition(generation); handled = true; break; } default: handled = BaseState::onMessageReceived(msg); break; Loading Loading @@ -7752,15 +7804,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( if (err != OK) { mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); // This is technically not correct, but appears to be // the only way to free the component instance. // Controlled transitioning from excecuting->idle // and idle->loaded seem impossible probably because // the output port never finishes re-enabling. mCodec->mShutdownInProgress = true; mCodec->mKeepComponentAllocated = false; mCodec->changeState(mCodec->mLoadedState); ALOGE("Error occurred while disabling the output port"); } return true; Loading @@ -7785,7 +7829,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( } default: return false; return BaseState::onOMXEvent(event, data1, data2); } } Loading Loading @@ -7987,6 +8031,11 @@ bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { case kWhatShutdown: { mCodec->deferMessage(msg); if (mCodec->mFatalError) { sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); msg->setInt32("generation", mCodec->mStateGeneration); msg->post(3000000); } break; } Loading @@ -7997,6 +8046,16 @@ bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatForceStateTransition: { int32_t generation = 0; CHECK(msg->findInt32("generation", &generation)); mCodec->forceStateTransition(generation); handled = true; break; } default: handled = BaseState::onMessageReceived(msg); break; Loading media/libstagefright/include/ACodec.h +6 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,7 @@ private: kWhatSubmitOutputMetadataBufferIfEOS = 'subm', kWhatOMXDied = 'OMXd', kWhatReleaseCodecInstance = 'relC', kWhatForceStateTransition = 'fstt', }; enum { Loading Loading @@ -305,6 +306,8 @@ private: std::shared_ptr<ACodecBufferChannel> mBufferChannel; int32_t mStateGeneration; enum { kExtensionsUnchecked, kExtensionsNone, Loading Loading @@ -569,6 +572,9 @@ private: // Send EOS on input stream. void onSignalEndOfInputStream(); // Force EXEC->IDLE->LOADED shutdown sequence if not stale. void forceStateTransition(int generation); DISALLOW_EVIL_CONSTRUCTORS(ACodec); }; Loading Loading
media/libstagefright/ACodec.cpp +71 −12 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ protected: virtual PortMode getPortMode(OMX_U32 portIndex); virtual void stateExited(); virtual bool onMessageReceived(const sp<AMessage> &msg); virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); Loading Loading @@ -553,6 +554,7 @@ ACodec::ACodec() mTunneled(false), mDescribeColorAspectsIndex((OMX_INDEXTYPE)0), mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0), mStateGeneration(0), mVendorExtensionsStatus(kExtensionsUnchecked) { mUninitializedState = new UninitializedState(this); mLoadedState = new LoadedState(this); Loading Loading @@ -5322,6 +5324,10 @@ ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( return KEEP_BUFFERS; } void ACodec::BaseState::stateExited() { ++mCodec->mStateGeneration; } bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatInputBufferFilled: Loading Loading @@ -5398,6 +5404,12 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { break; } case ACodec::kWhatForceStateTransition: { ALOGV("Already transitioned --- ignore"); break; } default: return false; } Loading Loading @@ -6988,7 +7000,6 @@ void ACodec::ExecutingState::resume() { void ACodec::ExecutingState::stateEntered() { ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); mCodec->processDeferredMessages(); } Loading Loading @@ -7614,6 +7625,30 @@ void ACodec::onSignalEndOfInputStream() { mCallback->onSignaledInputEOS(err); } void ACodec::forceStateTransition(int generation) { if (generation != mStateGeneration) { ALOGV("Ignoring stale force state transition message: #%d (now #%d)", generation, mStateGeneration); return; } ALOGE("State machine stuck"); // Error must have already been signalled to the client. // Deferred messages will be handled at LoadedState at the end of the // transition. mShutdownInProgress = true; // No shutdown complete callback at the end of the transition. mExplicitShutdown = false; mKeepComponentAllocated = true; status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); if (err != OK) { // TODO: do some recovery here. } else { changeState(mExecutingToIdleState); } } bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { mCodec->onFrameRendered(mediaTimeUs, systemNano); return true; Loading Loading @@ -7680,7 +7715,14 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( switch (msg->what()) { case kWhatFlush: case kWhatShutdown: case kWhatShutdown: { if (mCodec->mFatalError) { sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); msg->setInt32("generation", mCodec->mStateGeneration); msg->post(3000000); } // fall-through } case kWhatResume: case kWhatSetParameters: { Loading @@ -7693,6 +7735,16 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( break; } case kWhatForceStateTransition: { int32_t generation = 0; CHECK(msg->findInt32("generation", &generation)); mCodec->forceStateTransition(generation); handled = true; break; } default: handled = BaseState::onMessageReceived(msg); break; Loading Loading @@ -7752,15 +7804,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( if (err != OK) { mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); // This is technically not correct, but appears to be // the only way to free the component instance. // Controlled transitioning from excecuting->idle // and idle->loaded seem impossible probably because // the output port never finishes re-enabling. mCodec->mShutdownInProgress = true; mCodec->mKeepComponentAllocated = false; mCodec->changeState(mCodec->mLoadedState); ALOGE("Error occurred while disabling the output port"); } return true; Loading @@ -7785,7 +7829,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( } default: return false; return BaseState::onOMXEvent(event, data1, data2); } } Loading Loading @@ -7987,6 +8031,11 @@ bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { case kWhatShutdown: { mCodec->deferMessage(msg); if (mCodec->mFatalError) { sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); msg->setInt32("generation", mCodec->mStateGeneration); msg->post(3000000); } break; } Loading @@ -7997,6 +8046,16 @@ bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatForceStateTransition: { int32_t generation = 0; CHECK(msg->findInt32("generation", &generation)); mCodec->forceStateTransition(generation); handled = true; break; } default: handled = BaseState::onMessageReceived(msg); break; Loading
media/libstagefright/include/ACodec.h +6 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,7 @@ private: kWhatSubmitOutputMetadataBufferIfEOS = 'subm', kWhatOMXDied = 'OMXd', kWhatReleaseCodecInstance = 'relC', kWhatForceStateTransition = 'fstt', }; enum { Loading Loading @@ -305,6 +306,8 @@ private: std::shared_ptr<ACodecBufferChannel> mBufferChannel; int32_t mStateGeneration; enum { kExtensionsUnchecked, kExtensionsNone, Loading Loading @@ -569,6 +572,9 @@ private: // Send EOS on input stream. void onSignalEndOfInputStream(); // Force EXEC->IDLE->LOADED shutdown sequence if not stale. void forceStateTransition(int generation); DISALLOW_EVIL_CONSTRUCTORS(ACodec); }; Loading