From 8bdd0953532f16f6f3e413567536a6ddc2ce2d4e Mon Sep 17 00:00:00 2001 From: Shivaprasad Hongal Date: Fri, 11 Dec 2015 15:00:51 -0800 Subject: ACodec: Fix error handling in OutputPortSettingsChangedState Freeing the input buffers & node in ACodec::OutputPortSettingsChangedState on error, can cause NuPlayerDecoder to deference freed buffers. Instead of freeing the node internally on error in OutputPortSettingsChangedState, notify error to NuPlayer, and add kWhatShutDown handling to initiate Idle state transition. Change-Id: I7778d759c564fad27d266ac63d293bf0c30c029b --- media/libstagefright/ACodec.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'media') diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 4286d3c..ad4676f 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -6654,8 +6654,34 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( bool handled = false; switch (msg->what()) { - case kWhatFlush: case kWhatShutdown: + { + int32_t keepComponentAllocated; + CHECK(msg->findInt32( + "keepComponentAllocated", &keepComponentAllocated)); + + mCodec->mShutdownInProgress = true; + mCodec->mExplicitShutdown = true; + mCodec->mKeepComponentAllocated = keepComponentAllocated; + + status_t err = mCodec->mOMX->sendCommand( + mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); + if (err != OK) { + if (keepComponentAllocated) { + mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); + } + // TODO: do some recovery here. + } else { + // This is technically not correct, but appears to be + // the only way to free the component instance using + // ExectingToIdleState. + mCodec->changeState(mCodec->mExecutingToIdleState); + } + + handled = true; + break; + } + case kWhatFlush: case kWhatResume: case kWhatSetParameters: { @@ -6722,15 +6748,6 @@ 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); } return true; -- cgit v1.1