diff -r 481b3bce574a -r b6488ac24ddc omxil/omxilcomponentcommon/src/common/omxilfsm.cpp --- a/omxil/omxilcomponentcommon/src/common/omxilfsm.cpp Mon Aug 23 21:48:44 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,783 +0,0 @@ -// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: -// - - -/** - @file - @internalComponent -*/ - -#include "log.h" -#include "omxilfsm.h" -#include "omxilstate.h" -#include "omxilportmanager.h" -#include "omxilconfigmanager.h" -#include "omxilcallbackmanager.h" -#include "omxilprocessingfunction.h" - -#define RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(_a) \ - { \ - const OMX_ERRORTYPE _err = _a; \ - if (OMX_ErrorNone == _err) return _err; \ - else return SendOmxErrorEventIfNeeded(_err); \ - } - - -const TInt COmxILFsm::KMaxMsgQueueEntries; - -EXPORT_C COmxILFsm* -COmxILFsm::NewL(COmxILComponent& aComponent, - COmxILProcessingFunction& aProcFunction, - COmxILPortManager& aPortManager, - COmxILConfigManager& aConfigManager, - MOmxILCallbackManagerIf& aCallbacks) - { - DEBUG_PRINTF(_L8("COmxILFsm::NewLC")); - - COmxILFsm* self = new (ELeave) COmxILFsm(aComponent, - aProcFunction, - aPortManager, - aConfigManager, - aCallbacks); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return (self); - } - -void -COmxILFsm::ConstructL() - { - DEBUG_PRINTF(_L8("COmxILFsm::ConstructL")); - - // Create the FSM states - - // Init the array - for (TUint i=0; i < EStateMax; ++i) - { - iStates.AppendL(NULL); - } - - // Add the standard states... - iStates[EStateInvalid] = new (ELeave)COmxILStateInvalid; - iStates[EStateLoaded] = new (ELeave)COmxILStateLoaded; - iStates[EStateIdle] = new (ELeave)COmxILStateIdle; - iStates[EStateExecuting] = new (ELeave)COmxILStateExecuting; - iStates[EStatePause] = new (ELeave)COmxILStatePause; - iStates[EStateWaitForResources] = new (ELeave)COmxILStateWaitForResources; - - // Now add the substates - iStates[ESubStateLoadedToIdle] = new (ELeave)COmxILStateLoadedToIdle; - iStates[ESubStateIdleToLoaded] = new (ELeave)COmxILStateIdleToLoaded; - iStates[ESubStateExecutingToIdle] = new (ELeave)COmxILStateExecutingToIdle; - iStates[ESubStatePauseToIdle] = new (ELeave)COmxILStatePauseToIdle; - - iCallbacks.SetPortManager(iPortManager); - iCallbacks.SetFsm(*this); - - } - -COmxILFsm::COmxILFsm(COmxILComponent& aComponent, - COmxILProcessingFunction& aProcFunction, - COmxILPortManager& aPortManager, - COmxILConfigManager& aConfigManager, - MOmxILCallbackManagerIf& aCallbacks) - : - iComponent(aComponent), - iProcFunction(aProcFunction), - iPortManager(aPortManager), - iConfigManager(aConfigManager), - iCallbacks(aCallbacks), - iStates(), - iCurrentStateIndex(EStateMax), - ipCurrentState(0) - { - DEBUG_PRINTF(_L8("COmxILFsm::COmxILFsm")); - } - -COmxILFsm::~COmxILFsm() - { - DEBUG_PRINTF(_L8("COmxILFsm::~COmxILFsm")); - - iCurrentStateIndex = EStateMax; - ipCurrentState = 0; - iStates.ResetAndDestroy(); - - } - -OMX_ERRORTYPE -COmxILFsm::InitFsm() - { - DEBUG_PRINTF(_L8("COmxILFsm::InitFsm")); - - // Let's get ready to handle API calls... - iCurrentStateIndex = EStateLoaded; - ipCurrentState = iStates[iCurrentStateIndex]; - return OMX_ErrorNone; - - } - -COmxILComponent* -COmxILFsm::GetComponent() const - { - return &iComponent; - } - -OMX_ERRORTYPE -COmxILFsm::PopulateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr, - OMX_U32 aPortIndex, - OMX_PTR apAppPrivate, - OMX_U32 aSizeBytes, - OMX_U8* apBuffer) - { - DEBUG_PRINTF(_L8("COmxILFsm::PopulateBuffer")); - - TBool portPopulationCompleted = EFalse; - OMX_ERRORTYPE omxRetValue = - ipCurrentState->PopulateBuffer(*this, - appBufferHdr, - aPortIndex, - apAppPrivate, - aSizeBytes, - apBuffer, - portPopulationCompleted); - - if (OMX_ErrorNone == omxRetValue) - { - if (portPopulationCompleted && - ESubStateLoadedToIdle == iCurrentStateIndex && - iPortManager.AllPortsPopulated()) - { - // Complete here the transition to OMX_StateIdle - omxRetValue = FsmTransition(EStateIdle); - if (OMX_ErrorNone == omxRetValue) - { - // Notify the IL client that port population has - // completed sucessfully - omxRetValue = iCallbacks.TransitionCompleteNotification( - OMX_StateIdle); - - } - } - } - - if (OMX_ErrorNone == omxRetValue || - OMX_ErrorInsufficientResources == omxRetValue) - { - // OMX_ErrorInsufficientResources is allowed in OMX_EmptyThisBuffer and - // OMX_FillThisBuffer - return omxRetValue; - } - else - { - return SendOmxErrorEventIfNeeded(omxRetValue); - } - - } - -OMX_ERRORTYPE -COmxILFsm::FsmTransition(TStateIndex aNewState) - { - DEBUG_PRINTF2(_L8("COmxILFsm::FsmTransition : %d"), aNewState); - - __ASSERT_ALWAYS(aNewState < EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (aNewState != iCurrentStateIndex) - { - // We notify the processing function of all the state transitions, even - // if they are not to a final OpenMAX IL state. - OMX_ERRORTYPE omxRetValue; - if (OMX_ErrorNone != - (omxRetValue = - iProcFunction.StateTransitionIndication(aNewState))) - { - // No need of propagating further error codes if the component is - // transitioning to OMX_StateInvalid or if the PF itself is - // invalidating the component... - if (EStateInvalid != aNewState && - OMX_ErrorInvalidState != omxRetValue) - { - return omxRetValue; - } - } - - iCurrentStateIndex = aNewState; - ipCurrentState = iStates[iCurrentStateIndex]; - - } - - return OMX_ErrorNone; - - } - -OMX_ERRORTYPE -COmxILFsm::FsmTransition(TUint32 aNewState) - { - - return FsmTransition(static_cast(aNewState)); - - } - - -OMX_ERRORTYPE -COmxILFsm::GetComponentVersion(OMX_STRING aComponentName, - OMX_VERSIONTYPE* apComponentVersion, - OMX_VERSIONTYPE* apSpecVersion, - OMX_UUIDTYPE* apComponentUUID) const - { - DEBUG_PRINTF(_L8("COmxILFsm::GetComponentVersion")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - // This api should not be allowed in OMX_StateInvalid - if (EStateInvalid == iCurrentStateIndex) - { - return SendOmxErrorEventIfNeeded(OMX_ErrorInvalidState); - } - - if (!aComponentName || - !apComponentVersion || - !apSpecVersion || - !apComponentUUID) - { - return OMX_ErrorBadParameter; - } - - // This API call is independent of the current state. Its handled by the - // the config manager - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - iConfigManager.GetComponentVersion( - aComponentName, - apComponentVersion, - apSpecVersion, - apComponentUUID)); - } - - -OMX_ERRORTYPE -COmxILFsm::SendCommand(OMX_COMMANDTYPE aCommand, - TUint32 anParam1, - TAny* apCmdData) - { - DEBUG_PRINTF3(_L8("COmxILFsm::SendCommand : command [%d] Param1 [%d]"), aCommand, anParam1); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - // Do some very minor error checking here to try to save some time... - if (OMX_CommandStateSet == aCommand && - anParam1 > OMX_StateWaitForResources) - { - return OMX_ErrorBadParameter; - } - - TOmxILCommand command(aCommand, anParam1, apCmdData); - OMX_ERRORTYPE sendCommandError; - switch (aCommand) - { - case OMX_CommandStateSet: - { - sendCommandError = ipCurrentState->CommandStateSet(*this, command); - } - break; - case OMX_CommandFlush: - { - sendCommandError = ipCurrentState->CommandFlush(*this, command); - } - break; - case OMX_CommandPortDisable: - { - sendCommandError = ipCurrentState->CommandPortDisable(*this, command); - } - break; - case OMX_CommandPortEnable: - { - sendCommandError = ipCurrentState->CommandPortEnable(*this, command); - } - break; - case OMX_CommandMarkBuffer: - { - sendCommandError = ipCurrentState->CommandMarkBuffer(*this, command); - } - break; - default: - { - // This is an invalid command type - return OMX_ErrorBadParameter; - } - }; - - if (OMX_ErrorNone == sendCommandError || - OMX_ErrorInsufficientResources == sendCommandError) - { - // OMX_ErrorInsufficientResources is allowed in OMX_SendCommand - return sendCommandError; - } - else - { - return SendOmxErrorEventIfNeeded(sendCommandError); - } - - } - - -OMX_ERRORTYPE -COmxILFsm::GetParameter(OMX_INDEXTYPE aParamIndex, - TAny* apComponentParameterStructure) const - { - DEBUG_PRINTF(_L8("COmxILFsm::GetParameter")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apComponentParameterStructure) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->GetParameter(*this, aParamIndex, - apComponentParameterStructure)); - } - - -OMX_ERRORTYPE -COmxILFsm::SetParameter(OMX_INDEXTYPE aParamIndex, - const TAny* apComponentParameterStructure) - { - DEBUG_PRINTF(_L8("COmxILFsm::SetParameter")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apComponentParameterStructure) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->SetParameter(*this, aParamIndex, - apComponentParameterStructure)); - } - - -OMX_ERRORTYPE -COmxILFsm::GetConfig(OMX_INDEXTYPE aConfigIndex, - TAny* apComponentConfigStructure) const - { - DEBUG_PRINTF(_L8("COmxILFsm::GetConfig")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apComponentConfigStructure) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->GetConfig(*this, - aConfigIndex, - apComponentConfigStructure)); - - } - - -OMX_ERRORTYPE -COmxILFsm::SetConfig(OMX_INDEXTYPE aIndex, - const TAny* apComponentConfigStructure) - { - DEBUG_PRINTF(_L8("COmxILFsm::SetConfig")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apComponentConfigStructure) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->SetConfig(*this, aIndex, apComponentConfigStructure)); - - } - - -OMX_ERRORTYPE -COmxILFsm::GetExtensionIndex( - OMX_STRING aParameterName, - OMX_INDEXTYPE* apIndexType) const - { - DEBUG_PRINTF(_L8("COmxILFsm::GetExtensionIndex")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apIndexType || !aParameterName) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->GetExtensionIndex(*this, - aParameterName, - apIndexType)); - } - - -OMX_ERRORTYPE -COmxILFsm::GetState(OMX_STATETYPE* apState) const - { - DEBUG_PRINTF(_L8("COmxILFsm::GetState")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apState) - { - return OMX_ErrorBadParameter; - } - - *apState = ipCurrentState->GetState(); - - return OMX_ErrorNone; - - } - - -OMX_ERRORTYPE -COmxILFsm::ComponentTunnelRequest(OMX_U32 aPort, - OMX_HANDLETYPE aTunneledComp, - OMX_U32 aTunneledPort, - OMX_TUNNELSETUPTYPE* apTunnelSetup) - { - DEBUG_PRINTF(_L8("COmxILFsm::ComponentTunnelRequest")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - // Here, since NULL is a valid parameter for aTunneledComp, checking of - // input parameters is completely done by the ports. - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->ComponentTunnelRequest(*this, - aPort, - aTunneledComp, - aTunneledPort, - apTunnelSetup)); - - } - - -OMX_ERRORTYPE -COmxILFsm::UseBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr, - OMX_U32 aPortIndex, - OMX_PTR apAppPrivate, - OMX_U32 aSizeBytes, - OMX_U8* apBuffer) - { - DEBUG_PRINTF(_L8("COmxILFsm::UseBuffer")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!appBufferHdr || !aSizeBytes || !apBuffer) - { - return OMX_ErrorBadParameter; - } - - return PopulateBuffer(appBufferHdr, - aPortIndex, - apAppPrivate, - aSizeBytes, - apBuffer); - - } - - -OMX_ERRORTYPE -COmxILFsm::AllocateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr, - OMX_U32 aPortIndex, - OMX_PTR apAppPrivate, - OMX_U32 aSizeBytes) - { - DEBUG_PRINTF(_L8("COmxILFsm::AllocateBuffer")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!appBufferHdr || !aSizeBytes) - { - return OMX_ErrorBadParameter; - } - - - return PopulateBuffer(appBufferHdr, - aPortIndex, - apAppPrivate, - aSizeBytes, - 0); - - } - - -OMX_ERRORTYPE -COmxILFsm::FreeBuffer(OMX_U32 aPortIndex, - OMX_BUFFERHEADERTYPE* apBuffer) - { - DEBUG_PRINTF(_L8("COmxILFsm::FreeBuffer")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apBuffer) - { - return OMX_ErrorBadParameter; - } - - TBool portDepopulationCompleted = EFalse; - OMX_ERRORTYPE omxRetValue = - ipCurrentState->FreeBuffer(*this, - aPortIndex, - apBuffer, - portDepopulationCompleted); - - if (OMX_ErrorNone == omxRetValue) - { - if (portDepopulationCompleted) - { - if (ESubStateIdleToLoaded == iCurrentStateIndex) - { - if (iPortManager.AllPortsDePopulated()) - { - // Complete here the transition to OMX_StateLoaded - omxRetValue = FsmTransition(EStateLoaded); - if (OMX_ErrorNone == omxRetValue) - { - // Notify the IL client that port depopulation has - // completed sucessfully - omxRetValue = - iCallbacks.TransitionCompleteNotification( - OMX_StateLoaded); - } - } - } - } - } - - if (OMX_ErrorNone == omxRetValue) - { - return OMX_ErrorNone; - } - else - { - return SendOmxErrorEventIfNeeded(omxRetValue); - } - - } - - -OMX_ERRORTYPE -COmxILFsm::EmptyThisBuffer(OMX_BUFFERHEADERTYPE* apBuffer) - { - DEBUG_PRINTF2(_L8("COmxILFsm::EmptyThisBuffer : BUFFER [%X]"), apBuffer); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apBuffer) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->EmptyThisBuffer(*this, apBuffer)); - - } - - -OMX_ERRORTYPE -COmxILFsm::FillThisBuffer(OMX_BUFFERHEADERTYPE* apBuffer) - { - DEBUG_PRINTF2(_L8("COmxILFsm::FillThisBuffer : BUFFER [%X]"), apBuffer); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apBuffer) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - ipCurrentState->FillThisBuffer(*this, apBuffer)); - - } - - -OMX_ERRORTYPE -COmxILFsm::SetCallbacks(const OMX_CALLBACKTYPE* apCallbacks, - const OMX_PTR apAppData) - { - DEBUG_PRINTF(_L8("COmxILFsm::SetCallbacks")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - if (!apCallbacks) - { - return OMX_ErrorBadParameter; - } - - // This api should only be allowed in OMX_StateLoaded - if (EStateLoaded != iCurrentStateIndex) - { - return OMX_ErrorIncorrectStateOperation; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - iCallbacks.RegisterILClientCallbacks(apCallbacks, apAppData)); - - } - - -OMX_ERRORTYPE -COmxILFsm::UseEGLImage(OMX_BUFFERHEADERTYPE** /*appBufferHdr*/, - OMX_U32 /*aPortIndex*/, - OMX_PTR /*aAppPrivate*/, - void* /*eglImage*/) - { - DEBUG_PRINTF(_L8("COmxILFsm::UseEGLImage")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - return OMX_ErrorNotImplemented; - } - -OMX_ERRORTYPE -COmxILFsm::ComponentRoleEnum(OMX_U8* aRole, - OMX_U32 aIndex) const - { - DEBUG_PRINTF(_L8("COmxILFsm::ComponentRoleEnum")); - - __ASSERT_DEBUG(iCurrentStateIndex != EStateMax, - User::Panic(KOmxILFsmPanicCategory, 1)); - - // This api should not be allowed in OMX_StateInvalid - if (EStateInvalid == iCurrentStateIndex) - { - return SendOmxErrorEventIfNeeded(OMX_ErrorInvalidState); - } - - if (!aRole) - { - return OMX_ErrorBadParameter; - } - - RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED( - iConfigManager.ComponentRoleEnum(aRole, - aIndex)); - - } - -/** - This method is here to fullfill the following functionalities: - - -# It is used to make sure that the component error codes are returned to - the IL Client in a way that conforms with Table 3-9 of the OpenMAX IL - 1.1.1 spec. This table specifies which error codes must be sent with - EventHandler. If an error code is to be sent via EventHandler, the API - return code must be OMX_ErrorNone. - - -# This method is also used to invalidate the component whenever an internal - component action returns OMX_ErrorInvalidState. For example, this is - useful when code executed by a port or by the processing function cannot - recover from an internal error. Returning OMX_ErrorInvalidState in that - kind of situation will invalidate the component in - SendOmxErrorEventIfNeeded and the event will be conveyed to the IL Client - as mandated by the spec. - - @param aError An OpenMAX IL error code. - */ -OMX_ERRORTYPE -COmxILFsm::SendOmxErrorEventIfNeeded(OMX_ERRORTYPE aError) - { - DEBUG_PRINTF2(_L8("COmxILFsm::SendOmxErrorEventIfNeeded - aError = 0x%X"), aError); - - OMX_ERRORTYPE returnError = aError; - switch(aError) - { - case OMX_ErrorInsufficientResources: - { - DEBUG_PRINTF(_L8("COmxILFsm::SendOmxErrorEventIfNeeded aError[OMX_ErrorInsufficientResources]")); - iCallbacks.ErrorEventNotification(aError); - } - break; - case OMX_ErrorInvalidState: - { - DEBUG_PRINTF(_L8("COmxILFsm::SendOmxErrorEventIfNeeded aError[OMX_ErrorInvalidState]")); - iCallbacks.ErrorEventNotification(aError); - if (EStateInvalid != iCurrentStateIndex) - { - returnError = OMX_ErrorNone; - } - } - break; - case OMX_ErrorUnderflow: - case OMX_ErrorOverflow: - case OMX_ErrorHardware: - case OMX_ErrorStreamCorrupt: - case OMX_ErrorResourcesLost: - case OMX_ErrorSameState: - case OMX_ErrorResourcesPreempted: - case OMX_ErrorPortUnresponsiveDuringAllocation: - case OMX_ErrorPortUnresponsiveDuringDeallocation: - case OMX_ErrorPortUnresponsiveDuringStop: - case OMX_ErrorIncorrectStateTransition: - case OMX_ErrorPortUnpopulated: - case OMX_ErrorDynamicResourcesUnavailable: - case OMX_ErrorMbErrorsInFrame: - case OMX_ErrorFormatNotDetected: - { - DEBUG_PRINTF2(_L8("COmxILFsm::SendOmxErrorEventIfNeeded aError[%X]"), aError); - iCallbacks.ErrorEventNotification(aError); - returnError = OMX_ErrorNone; - } - break; - }; - - if(OMX_ErrorInvalidState == aError && - EStateInvalid != iCurrentStateIndex) - { - // Invalidate this component. This instance of the component should be - // destroyed by the IL Client after this. No need to check error code. - FsmTransition(EStateInvalid); - } - - return returnError; - - } - -OMX_ERRORTYPE -COmxILFsm::SendOmxErrorEventIfNeeded(OMX_ERRORTYPE aError) const - { - DEBUG_PRINTF(_L8("COmxILFsm::SendOmxErrorEventIfNeeded")); - - return const_cast(this)->SendOmxErrorEventIfNeeded(aError); - - }