diff -r 000000000000 -r 0e4a32b9112d omxil_generic/omxilcomplib/src/omxilportmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxil_generic/omxilcomplib/src/omxilportmanager.cpp Wed Aug 25 12:40:50 2010 +0300 @@ -0,0 +1,2178 @@ +// 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 "omxilportmanager.h" +#include +#include "omxilcallbackmanager.h" +#include + + /** + Static NewL for two-phase construction + + @param aProcessingFunction The component's processing function + + @param aCallbacks The component's callback manager + + @param aOmxVersion The IL Spec version in use + + @param aNumberOfAudioPorts Number of audio ports in the component + + @param aStartAudioPortNumber The start index for audio ports + + @param aNumberOfImagePorts Number of image ports in the component + + @param aStartImagePortNumber The start index for image ports + + @param aNumberOfVideoPorts Number of video ports in the component + + @param aStartVideoPortNumber The start index for video ports + + @param aNumberOfOtherPorts Number of other ports in the component + + @param aStartOtherPortNumber The start index for other ports + + @param aImmediateReturnTimeBuffer This only applies to components with a + clock client port. Indicates whether the Port Manager must forward an + arriving clock buffer to the Callback Manager (ETrue) or to the + Processing Function (EFalse) . If the clock buffer is to be forwarded to + the Processing Function, this will happen using the BufferIndication + function of the component's PF. Otherwise, PF's MediaTimeIndication is + used instead. + */ +COmxILPortManager* +COmxILPortManager::NewL( + COmxILProcessingFunction& aProcessingFunction, + MOmxILCallbackManagerIf& aCallbacks, + const OMX_VERSIONTYPE& aOmxVersion, + OMX_U32 aNumberOfAudioPorts, + OMX_U32 aStartAudioPortNumber, + OMX_U32 aNumberOfImagePorts, + OMX_U32 aStartImagePortNumber, + OMX_U32 aNumberOfVideoPorts, + OMX_U32 aStartVideoPortNumber, + OMX_U32 aNumberOfOtherPorts, + OMX_U32 aStartOtherPortNumber, + OMX_BOOL aImmediateReturnTimeBuffer) + { + DEBUG_PRINTF(_L8("COmxILPortManager::NewL")); + + COmxILPortManager* self = + new (ELeave)COmxILPortManager( + aProcessingFunction, + aCallbacks); + + CleanupStack::PushL(self); + self->ConstructL(aProcessingFunction, + aCallbacks, + aOmxVersion, + aNumberOfAudioPorts, + aStartAudioPortNumber, + aNumberOfImagePorts, + aStartImagePortNumber, + aNumberOfVideoPorts, + aStartVideoPortNumber, + aNumberOfOtherPorts, + aStartOtherPortNumber, + aImmediateReturnTimeBuffer); + CleanupStack::Pop(self); + return self; + } + +void +COmxILPortManager::ConstructL( + COmxILProcessingFunction& /* aProcessingFunction */, + MOmxILCallbackManagerIf& /* aCallbacks */, + const OMX_VERSIONTYPE& aOmxVersion, + OMX_U32 aNumberOfAudioPorts, + OMX_U32 aStartAudioPortNumber, + OMX_U32 aNumberOfImagePorts, + OMX_U32 aStartImagePortNumber, + OMX_U32 aNumberOfVideoPorts, + OMX_U32 aStartVideoPortNumber, + OMX_U32 aNumberOfOtherPorts, + OMX_U32 aStartOtherPortNumber, + OMX_BOOL aImmediateReturnTimeBuffer) + { + DEBUG_PRINTF(_L8("COmxILPortManager::ConstructL")); + + iImmediateReturnTimeBuffer = aImmediateReturnTimeBuffer; + + iAudioParamInit.nSize = sizeof(OMX_PORT_PARAM_TYPE); + iAudioParamInit.nVersion = aOmxVersion; + iAudioParamInit.nPorts = aNumberOfAudioPorts; + iAudioParamInit.nStartPortNumber = aStartAudioPortNumber; + + iImageParamInit.nSize = sizeof(OMX_PORT_PARAM_TYPE); + iImageParamInit.nVersion = aOmxVersion; + iImageParamInit.nPorts = aNumberOfImagePorts; + iImageParamInit.nStartPortNumber = aStartImagePortNumber; + + iVideoParamInit.nSize = sizeof(OMX_PORT_PARAM_TYPE); + iVideoParamInit.nVersion = aOmxVersion; + iVideoParamInit.nPorts = aNumberOfVideoPorts; + iVideoParamInit.nStartPortNumber = aStartVideoPortNumber; + + iOtherParamInit.nSize = sizeof(OMX_PORT_PARAM_TYPE); + iOtherParamInit.nVersion = aOmxVersion; + iOtherParamInit.nPorts = aNumberOfOtherPorts; + iOtherParamInit.nStartPortNumber = aStartOtherPortNumber; + + + InsertParamIndexL(OMX_IndexParamAudioInit); + InsertParamIndexL(OMX_IndexParamImageInit); + InsertParamIndexL(OMX_IndexParamVideoInit); + InsertParamIndexL(OMX_IndexParamOtherInit); + + + if(iAudioParamInit.nStartPortNumber != 0) + { + User::Leave(KErrArgument); + } + + if (iImageParamInit.nPorts > 0) + { + if (iAudioParamInit.nPorts != + iImageParamInit.nStartPortNumber) + { + User::Leave(KErrArgument); + } + } + + if (iVideoParamInit.nPorts > 0) + { + if ((iAudioParamInit.nPorts + + iImageParamInit.nPorts) != + iVideoParamInit.nStartPortNumber) + { + User::Leave(KErrArgument); + } + } + + if (iOtherParamInit.nPorts > 0) + { + if ((iAudioParamInit.nPorts + + iImageParamInit.nPorts + + iVideoParamInit.nPorts) != + iOtherParamInit.nStartPortNumber) + { + User::Leave(KErrArgument); + } + } + + } + +COmxILPortManager::COmxILPortManager( + COmxILProcessingFunction& aProcessingFunction, + MOmxILCallbackManagerIf& aCallbacks) + : + iProcessingFunction(aProcessingFunction), + iCallbacks(aCallbacks), + iAllPorts() + { + DEBUG_PRINTF(_L8("COmxILPortManager::COmxILPortManager")); + + } + +COmxILPortManager::~COmxILPortManager() + { + DEBUG_PRINTF(_L8("COmxILPortManager::~COmxILPortManager")); + iAllPorts.ResetAndDestroy(); + iTimePorts.Close(); + } + +void +COmxILPortManager::AppendPortL(const COmxILPort* aPort) + { + DEBUG_PRINTF(_L8("COmxILPortManager::AppendPort")); + + const TInt portCount = iAllPorts.Count(); + OMX_PORTDOMAINTYPE portDomain = aPort->Domain(); + OMX_U32 startPortNumber = 0; + TBool timePort = EFalse; + + switch(portDomain) + { + case OMX_PortDomainAudio: + { + __ASSERT_ALWAYS(portCount >= 0, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + __ASSERT_ALWAYS(portCount < iAudioParamInit.nPorts, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + + startPortNumber = iAudioParamInit.nStartPortNumber; + + } + break; + + case OMX_PortDomainImage: + { + __ASSERT_ALWAYS(portCount >= iAudioParamInit.nPorts, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + __ASSERT_ALWAYS(portCount < + iAudioParamInit.nPorts + + iImageParamInit.nPorts, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + + startPortNumber = iImageParamInit.nStartPortNumber; + + } + break; + + case OMX_PortDomainVideo: + { + __ASSERT_ALWAYS(portCount >= + iAudioParamInit.nPorts + + iImageParamInit.nPorts, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + __ASSERT_ALWAYS(portCount < + iAudioParamInit.nPorts + + iImageParamInit.nPorts + + iVideoParamInit.nPorts, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + + startPortNumber = iVideoParamInit.nStartPortNumber; + + } + break; + + + case OMX_PortDomainOther: + { + __ASSERT_ALWAYS(portCount >= + iAudioParamInit.nPorts + + iImageParamInit.nPorts + + iVideoParamInit.nPorts, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + __ASSERT_ALWAYS(portCount < + iAudioParamInit.nPorts + + iImageParamInit.nPorts + + iVideoParamInit.nPorts + + iOtherParamInit.nPorts, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + + startPortNumber = iOtherParamInit.nStartPortNumber; + + OMX_OTHER_PARAM_PORTFORMATTYPE paramFormat; + paramFormat.nSize = sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE); + paramFormat.nVersion = TOmxILSpecVersion(); + paramFormat.nPortIndex = aPort->Index(); + paramFormat.nIndex = 0; + + if ((aPort->GetParameter(OMX_IndexParamOtherPortFormat, ¶mFormat) == OMX_ErrorNone) && + paramFormat.eFormat == OMX_OTHER_FormatTime) + { + timePort = ETrue; + } + } + + break; + + default: + { + User::Panic(KOmxILPortManagerPanicCategory, 1); + } + }; + + if(portCount == startPortNumber) + { + iAllPorts.AppendL(aPort); + } + else + { + for (TInt i=startPortNumber; iIndex() >= aPort->Index()) + { + User::Panic(KOmxILPortManagerPanicCategory, 1); + } + } + iAllPorts.AppendL(aPort); + } + + + TRAPD(err, iTimePorts.AppendL(timePort)); + if (KErrNone != err) + { + iAllPorts.Remove(iAllPorts.Count()-1); + User::Leave(err); + } + } + +void COmxILPortManager::RemoveLastAppendedPort() + { + if (iAllPorts.Count()>0 && iTimePorts.Count()>0) + { + iAllPorts.Remove(iAllPorts.Count()-1); + iTimePorts.Remove(iTimePorts.Count()-1); + } + } + + +/** + This method is used at component's construction time, i.e., in a factory + method of the component. The main component object uses this method to add + the component's ports to its port manager instance. + + @param aPort The port instance to be added. + + @param aDirection The direction of the port being added. + + @ return A Symbian error code indicating if the function call was + successful. KErrNone on success, otherwise another of the system-wide error + codes. +*/ +TInt +COmxILPortManager::AddPort(const COmxILPort* aPort, + OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF(_L8("COmxILPortManager::AddPort")); + + __ASSERT_ALWAYS(aPort, User::Panic(KOmxILPortManagerPanicCategory, 1)); + + if (iAllPorts.Count() >= (iAudioParamInit.nPorts + + iVideoParamInit.nPorts + + iImageParamInit.nPorts + + iOtherParamInit.nPorts)) + { + return KErrArgument; + } + + if (aPort->Direction() != aDirection) + { + return KErrArgument; + } + + if (iAllPorts.Find(aPort) != KErrNotFound) + { + return KErrArgument; + } + + OMX_ERRORTYPE omxRetValue = + aPort->GetLocalOmxParamIndexes(ManagedParamIndexes()); + if (OMX_ErrorNone == omxRetValue) + { + omxRetValue = aPort->GetLocalOmxConfigIndexes(ManagedConfigIndexes()); + } + + if (OMX_ErrorNone != omxRetValue) + { + if (OMX_ErrorInsufficientResources == omxRetValue) + { + return KErrNoMemory; + } + else + { + return KErrGeneral; + } + } + + TRAPD(err, AppendPortL(aPort)); + if (KErrNone != err) + { + return err; + } + + // Here, let's register this port into the call back manager so buffer + // marks can be propagated to the right port... + const OMX_U32 propagationPortIndex = aPort->BufferMarkPropagationPort(); + if (propagationPortIndex != COmxILPort::KBufferMarkPropagationPortNotNeeded) + { + omxRetValue = iCallbacks.RegisterBufferMarkPropagationPort(aPort->Index(), + propagationPortIndex); + } + + err = KErrNone; + if (OMX_ErrorNone != omxRetValue) + { + RemoveLastAppendedPort(); + switch (omxRetValue) + { + case OMX_ErrorInsufficientResources: + { + err = KErrNoMemory; + } + break; + default: + { + err = KErrGeneral; + } + }; + } + + return err; + + } + +TBool +COmxILPortManager::RemoveBuffersFromPfOrCm( + COmxILPort* apPort, OMX_BOOL aRemoveFromPfOnly /* = OMX_FALSE */) const + { + __ASSERT_DEBUG(apPort, User::Panic(KOmxILPortManagerPanicCategory, 1)); + DEBUG_PRINTF3(_L8("COmxILPortManager::RemoveBuffersFromPfOrCm: PORT[%d] aRemoveFromPfOnly[%s] "), + apPort->Index(), aRemoveFromPfOnly ? "TRUE" : "FALSE"); + + const TInt headerCount = apPort->Count(); + OMX_BUFFERHEADERTYPE* pHeader = 0; + TBool allHeadersRemovedFromPf = ETrue; + for (TInt j=0; jIsBufferAtHome(pHeader)) + { + // Tell the PF to remove this header from its queues... + if (!iProcessingFunction.BufferRemovalIndication( + pHeader, + apPort->Direction())) + { + if (OMX_FALSE == aRemoveFromPfOnly) + { + if (!iCallbacks.BufferRemovalIndication( + pHeader, + apPort->Direction())) + { + allHeadersRemovedFromPf = EFalse; + } + else + { + apPort->SetBufferReturned(pHeader); + // Make sure the buffer contents are cleared + TOmxILUtil::ClearBufferContents(pHeader); + } + } + } + else + { + apPort->SetBufferReturned(pHeader); + // Make sure the buffer contents are cleared + TOmxILUtil::ClearBufferContents(pHeader); + } + } + } + + return allHeadersRemovedFromPf; + + } + +OMX_ERRORTYPE +COmxILPortManager::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + DEBUG_PRINTF(_L8("COmxILPortManager::GetParameter")); + + TInt index = FindParamIndex(aParamIndex); + if (KErrNotFound == index) + { + return OMX_ErrorUnsupportedIndex; + } + + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + switch(aParamIndex) + { + case OMX_IndexParamAudioInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamOtherInit: + { + if (OMX_ErrorNone != + (omxRetValue = + TOmxILUtil::CheckOmxStructSizeAndVersion( + const_cast(apComponentParameterStructure), + sizeof(OMX_PORT_PARAM_TYPE)))) + { + return omxRetValue; + } + + OMX_PORT_PARAM_TYPE* + pPortParamType + = static_cast( + apComponentParameterStructure); + + switch(aParamIndex) + { + case OMX_IndexParamAudioInit: + *pPortParamType = iAudioParamInit; + break; + case OMX_IndexParamImageInit: + *pPortParamType = iImageParamInit; + break; + case OMX_IndexParamVideoInit: + *pPortParamType = iVideoParamInit; + break; + case OMX_IndexParamOtherInit: + *pPortParamType = iOtherParamInit; + break; + } + + } + break; + + default: + { + // Obtain the port index + OMX_U32 portIndex; + if (OMX_ErrorNone != GetPortIndexFromOmxStruct( + apComponentParameterStructure, + portIndex)) + { + return OMX_ErrorBadPortIndex; + } + + // Now delegate to the specific port + return iAllPorts[portIndex]->GetParameter( + aParamIndex, + apComponentParameterStructure); + } + }; + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + OMX_BOOL aPortIsDisabled /* = OMX_FALSE */ ) + { + DEBUG_PRINTF(_L8("COmxILPortManager::SetParameter")); + + TInt index = FindParamIndex(aParamIndex); + if (KErrNotFound == index) + { + return OMX_ErrorUnsupportedIndex; + } + + // Obtain the port index + OMX_U32 portIndex; + if (OMX_ErrorNone != GetPortIndexFromOmxStruct( + apComponentParameterStructure, + portIndex)) + { + return OMX_ErrorBadPortIndex; + } + + DEBUG_PRINTF2(_L8("COmxILPortManager::SetParameter : PORT[%u]"), portIndex); + + // Grab the port here... + COmxILPort* pPort = iAllPorts[portIndex]; + + if (OMX_TRUE == aPortIsDisabled && + pPort->IsEnabled() && + !pPort->IsTransitioningToEnabled()) + { + // There is an indication from the FSM that the port must be disabled, + // otherwise, this is not allowed in the current state. + return OMX_ErrorIncorrectStateOperation; + } + + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + switch(aParamIndex) + { + case OMX_IndexParamAudioInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamOtherInit: + { + // Don't allow changes in the OMX_PORT_PARAM_TYPE structure + return OMX_ErrorUnsupportedIndex; + } + default: + { + TBool updateProcessingFunction = EFalse; + omxRetValue = + pPort->SetParameter( + aParamIndex, + apComponentParameterStructure, + updateProcessingFunction); + + if (OMX_ErrorNone == omxRetValue) + { + if (updateProcessingFunction) + { + omxRetValue = iProcessingFunction.ParamIndication( + aParamIndex, + apComponentParameterStructure); + } + } + + } + }; + + return omxRetValue; + + } + +OMX_ERRORTYPE +COmxILPortManager::GetConfig(OMX_INDEXTYPE aConfigIndex, + TAny* apComponentConfigStructure) const + { + DEBUG_PRINTF(_L8("COmxILPortManager::GetConfig")); + + TInt index = FindConfigIndex(aConfigIndex); + if (KErrNotFound == index) + { + return OMX_ErrorUnsupportedIndex; + } + + // Obtain the port index + OMX_U32 portIndex; + if (OMX_ErrorNone != GetPortIndexFromOmxStruct(apComponentConfigStructure, + portIndex)) + { + return OMX_ErrorBadPortIndex; + } + + // Now delegate to the specific port + return iAllPorts[portIndex]->GetConfig( + aConfigIndex, + apComponentConfigStructure); + + } + +OMX_ERRORTYPE +COmxILPortManager::SetConfig(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure) + { + DEBUG_PRINTF(_L8("COmxILPortManager::SetConfig")); + +#ifdef _OMXIL_COMMON_IL516C_ON + + if (OMX_IndexConfigPortBufferReturnRequest == aConfigIndex) + { + OMX_U32 portIndex; + if (OMX_ErrorNone != GetPortIndexFromOmxStruct( + apComponentConfigStructure, + portIndex)) + { + return OMX_ErrorBadPortIndex; + } + DEBUG_PRINTF2(_L8("COmxILPortManager::SetConfig : PORT[%u] OMX_IndexConfigPortBufferReturnRequest"), portIndex); + + // Check the index of the port.. + if ((OMX_ALL != portIndex) && + (CheckPortIndex(portIndex) != OMX_ErrorNone)) + { + return OMX_ErrorBadPortIndex; + } + + // This error will be ignored... + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + if (portIndex != OMX_ALL) + { + omxRetValue = BufferEjectIndication(portIndex); + } + else + { + const TInt portCount = iAllPorts.Count(); + + for (TUint i = 0; i< portCount; ++i) + { + omxRetValue = BufferEjectIndication(iAllPorts[i]->Index()); + } + } + + return OMX_ErrorNone; + + } +#endif + + TInt index = FindConfigIndex(aConfigIndex); + if (KErrNotFound == index) + { + return OMX_ErrorUnsupportedIndex; + } + + // Obtain the port index + OMX_U32 portIndex; + if (OMX_ErrorNone != GetPortIndexFromOmxStruct(apComponentConfigStructure, + portIndex)) + { + return OMX_ErrorBadPortIndex; + } + + DEBUG_PRINTF2(_L8("COmxILPortManager::SetConfig : PORT[%u]"), portIndex); + + TBool updateProcessingFunction = EFalse; + OMX_ERRORTYPE omxRetValue = + iAllPorts[portIndex]->SetConfig( + aConfigIndex, + apComponentConfigStructure, + updateProcessingFunction); + + if (OMX_ErrorNone == omxRetValue) + { + if (updateProcessingFunction) + { + omxRetValue = iProcessingFunction.ConfigIndication( + aConfigIndex, + apComponentConfigStructure); + } + } + + return omxRetValue; + + } + +OMX_ERRORTYPE +COmxILPortManager::GetExtensionIndex( + OMX_STRING aParameterName, + OMX_INDEXTYPE* apIndexType) const + { + DEBUG_PRINTF(_L8("COmxILPortManager::GetExtensionIndex")); + + // See if the extension index is supported by any of the ports... + const TInt portCount = iAllPorts.Count(); + OMX_ERRORTYPE retValue = OMX_ErrorNone; + for (TUint i = 0; i< portCount; ++i) + { + retValue = iAllPorts[i]->GetExtensionIndex(aParameterName, + apIndexType); + if (retValue != OMX_ErrorUnsupportedIndex) + { + return retValue; + } + } + + return OMX_ErrorUnsupportedIndex; + + } + +OMX_ERRORTYPE +COmxILPortManager::PopulateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr, + OMX_U32 aPortIndex, + OMX_PTR apAppPrivate, + OMX_U32 aSizeBytes, + OMX_U8* apBuffer, + TBool& portPopulationCompleted, + OMX_BOOL aPortIsDisabled /* = OMX_FALSE */ ) + { + DEBUG_PRINTF(_L8("COmxILPortManager::PopulateBuffer")); + + // Check the index of the port.. + if (CheckPortIndex(aPortIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + // Grab the port here... + COmxILPort* pPort = iAllPorts[aPortIndex]; + +#ifdef _OMXIL_COMMON_IL516C_ON + if (!apBuffer) + { + // Basically, if OMX_UseBuffer is used, the port must not be populated + // at this point, otherwise it is an error... + if (pPort->IsPopulated()) + { + return OMX_ErrorIncorrectStateOperation; + } + } + else + { + // ... AllocateBuffer... this is only allowed if the the IL Client has + // issued the command to idle already.. +#endif + + if (OMX_TRUE == aPortIsDisabled && + pPort->IsEnabled() && + !pPort->IsTransitioningToEnabled()) + { + // There is an indication from the FSM that the port must be disabled, + // otherwise, the buffer allocation is not allowed in the current + // state. Note that a port may be transitioning to enabled and in that + // case the buffer population must be allowed... + return OMX_ErrorIncorrectStateOperation; + } + +#ifdef _OMXIL_COMMON_IL516C_ON + } +#endif + + // Check that in case of tunnelling, this port is not buffer supplier... + if (pPort->IsTunnelledAndBufferSupplier()) + { + return OMX_ErrorBadPortIndex; + } + + // Now delegate to the port... + OMX_ERRORTYPE omxRetValue; + if (OMX_ErrorNone != (omxRetValue = pPort->PopulateBuffer( + appBufferHdr, + apAppPrivate, + aSizeBytes, + apBuffer, + portPopulationCompleted))) + { + return omxRetValue; + } + + if (portPopulationCompleted && pPort->IsTransitioningToEnabled()) + { + // This is a case of port being enabled... Inform the port that it + // has been enabled.. + pPort->SetTransitionToEnabledCompleted(); + + // For each enabled port, the IL Client must be notified with an + // enabled completion event... + omxRetValue = iCallbacks.CommandCompleteNotification( + OMX_CommandPortEnable, pPort->Index()); + } + + return omxRetValue; + + } + + +OMX_ERRORTYPE +COmxILPortManager::FreeBuffer(OMX_U32 aPortIndex, + OMX_BUFFERHEADERTYPE* apBufferHeader, + TBool& portDepopulationCompleted, + OMX_BOOL aPortIsDisabled /* = OMX_FALSE */) + { + DEBUG_PRINTF3(_L8("COmxILPortManager::FreeBuffer : PORT[%u] BUFFER [%X]"), aPortIndex, apBufferHeader); + + // Check the index of the port.. + if (CheckPortIndex(aPortIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + // Grab the port here... + COmxILPort* pPort = iAllPorts[aPortIndex]; + + // Check that in case of tunnelling, this port is not buffer supplier... + if (pPort->IsTunnelledAndBufferSupplier()) + { + return OMX_ErrorBadPortIndex; + } + + TBool errorPortUnpopulated = EFalse; + if (OMX_TRUE == aPortIsDisabled && + pPort->IsEnabled()) + { + // There is an indication from the FSM that the port should be + // disabled. If that's not the case, the buffer deallocation will raise + // an OMX_ErrorPortUnpopulated error in the current state. + + if (!pPort->IsBufferAtHome(apBufferHeader)) + { + // FreeBuffer will normally be called in a situation where we are + // not suppliers and the supplier already got the buffer. So the + // buffer won't be on our side almost never. + + if (!iTimePorts[aPortIndex] || !iImmediateReturnTimeBuffer) + { + // We'll tell the PF to remove this + // header from its queues, in case this is called in some strange + // situation (should not happen if the tunnelled component is well + // behaved)... + iProcessingFunction.BufferRemovalIndication( + apBufferHeader, + pPort->Direction()); + } + + // Set the returned flag as this buffer will not count as "away" + // anymore... + pPort->SetBufferReturned(apBufferHeader); + } + + // We have to send the Port Unpopulated Error... + errorPortUnpopulated = ETrue; + } + + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + // Now delegate to the port... + if (OMX_ErrorNone != (omxRetValue = pPort->FreeBuffer( + apBufferHeader, + portDepopulationCompleted))) + { + return omxRetValue; + } + + if (errorPortUnpopulated) + { + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.ErrorEventNotification(OMX_ErrorPortUnpopulated))) + { + return omxRetValue; + } + } + + + if (portDepopulationCompleted) + { + if (pPort->IsTransitioningToDisabled()) + { + // Here we must complete the OMX_CommandPortDisable command + + // Set the state of the port to disabled as the command has already + // completed... + pPort->SetTransitionToDisabledCompleted(); + + // For each disabled port, the IL Client must be notified + // with a disabled completion event... + omxRetValue = iCallbacks.CommandCompleteNotification( + OMX_CommandPortDisable, aPortIndex); + + // Clear this flag here. Otherwise, the FSM would inform the client + // of a successful transition to OMX_StateIdle which is not the + // case... + portDepopulationCompleted = EFalse; + } + } + + return omxRetValue; + + } + +OMX_ERRORTYPE +COmxILPortManager::TunnelRequest(OMX_U32 aPortIndex, + OMX_HANDLETYPE aTunneledComp, + OMX_U32 aTunneledPort, + OMX_TUNNELSETUPTYPE* apTunnelSetup, + OMX_BOOL aPortIsDisabled /* = OMX_FALSE */) + { + DEBUG_PRINTF3(_L8("COmxILPortManager::TunnelRequest : aTunneledComp [%X] aTunneledPort [%d]"), aTunneledComp, aTunneledPort); + + // Check the index of the port.. + if (CheckPortIndex(aPortIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + // Grab the port here... + COmxILPort* pPort = iAllPorts[aPortIndex]; + + if (OMX_TRUE == aPortIsDisabled && + pPort->IsEnabled()) + { + // There is an indication from the FSM that the port must be disabled, + // otherwise, the tunnel request is not allowed in the current state. + return OMX_ErrorIncorrectStateOperation; + } + + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + // Check whether the tunnel is being torn down... + if (!aTunneledComp) + { + // Tell the port... + if (OMX_ErrorNone != + (omxRetValue = pPort->TunnelRequest( + aTunneledComp, + aTunneledPort, + apTunnelSetup))) + { + return omxRetValue; + } + + if (OMX_ErrorNone != + (omxRetValue = iCallbacks.DeregisterTunnelCallback(aPortIndex))) + { + // This is serious enough... + return OMX_ErrorInvalidComponent; + } + + // We are done here... + return OMX_ErrorNone; + } + + // Check whether the port is being re-tunnelled... + if (pPort->IsTunnelled()) + { + // Only two valid options here: + // 1.- The port is completely disabled... + // or... + // 2.- The port is enabled AND component in OMX_StateLoaded + if ((!pPort->IsEnabled() && + !pPort->IsTransitioningToEnabled() && + !pPort->IsTransitioningToDisabled()) + || + (pPort->IsEnabled() && !aPortIsDisabled)) + { + if (OMX_ErrorNone != + (omxRetValue = iCallbacks.DeregisterTunnelCallback(aPortIndex))) + { + return OMX_ErrorInvalidComponent; + } + } + else + { + return OMX_ErrorIncorrectStateOperation; + } + } + + // Delegate to the port... + if (OMX_ErrorNone != + (omxRetValue = pPort->TunnelRequest( + aTunneledComp, + aTunneledPort, + apTunnelSetup))) + { + return omxRetValue; + } + + // From this point on, the port will assume that a tunnel has been + // successfully created. If there is a problem at other end, the IL Client + // will clear the tunnel on this side using ComponentTunnelRequest with + // NULL handle parameter + + // Register the existence of a tunnel within the callback manager... + if (OMX_ErrorNone != + (omxRetValue = iCallbacks.RegisterTunnelCallback(aPortIndex, + pPort->Direction(), + aTunneledComp, + aTunneledPort))) + { + // This is serious enough... + return OMX_ErrorInvalidComponent; + } + + return OMX_ErrorNone; + + } + + +OMX_ERRORTYPE +COmxILPortManager::TunnellingBufferAllocation(TBool& aComponentPopulationCompleted, + TUint32 aPortIndex /* = OMX_ALL */) + { + DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferAllocation")); + + aComponentPopulationCompleted = EFalse; + + // Check the index of the port.. + if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone)) + { + return OMX_ErrorBadPortIndex; + } + + const TInt portCount = iAllPorts.Count(); + COmxILPort* pPort = 0; + OMX_U32 portIndex = 0; + TInt i=0; + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + do + { + if (aPortIndex != OMX_ALL) + { + // Grab the port here... + pPort = iAllPorts[aPortIndex]; + portIndex = aPortIndex; + } + else + { + pPort = iAllPorts[i]; + portIndex = pPort->Index(); + } + + + if (pPort->IsEnabled() && + pPort->IsTunnelledAndBufferSupplier() && + !pPort->IsPopulated()) + { + TBool portPopulationCompleted = EFalse; + if (OMX_ErrorNone != + (omxRetValue = pPort->PopulateTunnel(portPopulationCompleted))) + { + // TODO: Check case of ports being enabled (error callback needed...) + return omxRetValue; + } + + if (portPopulationCompleted && pPort->IsTransitioningToEnabled()) + { + // This is a case of port being enabled... Inform the port that it + // has been enabled.. + pPort->SetTransitionToEnabledCompleted(); + + // For each enabled port, the IL Client must be notified with an + // enabled completion event... + if (OMX_ErrorNone != ( + omxRetValue = iCallbacks.CommandCompleteNotification( + OMX_CommandPortEnable, portIndex))) + { + return omxRetValue; + } + } + + } + + // Increment loop counter + ++i; + } + while (OMX_ALL == aPortIndex && i < portCount); + + if (AllPortsPopulated()) + { + DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferAllocation : AllPortsPopulated : [TRUE]")); + aComponentPopulationCompleted = ETrue; + } + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::TunnellingBufferDeallocation( + TBool& aComponentDepopulationCompleted) + { + DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferDeallocation")); + + aComponentDepopulationCompleted = EFalse; + + const TInt portCount = iAllPorts.Count(); + COmxILPort* pPort = 0; + TInt portDepopulationCounter = 0; + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + TBool portDepopulationCompleted = EFalse; + for (TInt i=0; iIsEnabled() && pPort->IsTunnelledAndBufferSupplier()) + { + // TODO: Check that at this point, the ProcessingFunction must not + // hold any buffer header... + portDepopulationCompleted = EFalse; + if (OMX_ErrorNone != + (omxRetValue = pPort->FreeTunnel(portDepopulationCompleted))) + { + return omxRetValue; + } + + if (pPort->IsDePopulated()) + { + portDepopulationCounter++; + } + } + } + + if (AllPortsDePopulated()) + { + DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferDeallocation : AllPortsDepopulated : [TRUE]")); + aComponentDepopulationCompleted = ETrue; + } + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::InitiateTunnellingDataFlow( + OMX_U32 aPortIndex /* = OMX_ALL */, + OMX_BOOL aSuppliersAndNonSuppliers /* = OMX_FALSE */) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::InitiateTunnellingDataFlow : PORT[%d]"), aPortIndex); + + // Check the index of the port.. + if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone)) + { + return OMX_ErrorBadPortIndex; + } + + // This is an indication that the component is ready to start exchanging + // buffers... Supplier tunnelled ports must initiate the buffer exchange in + // the tunnel... + const TInt portCount = iAllPorts.Count(); + COmxILPort* pPort = 0; + OMX_U32 portIndex = 0; + TInt i=0; + do + { + if (aPortIndex != OMX_ALL) + { + // Grab the port here... + pPort = iAllPorts[aPortIndex]; + portIndex = aPortIndex; + } + else + { + pPort = iAllPorts[i]; + portIndex = pPort->Index(); + } + + if (pPort->IsEnabled() && + ((OMX_TRUE == aSuppliersAndNonSuppliers) || + pPort->IsTunnelledAndBufferSupplier())) + { + const TInt headerCount = pPort->Count(); + OMX_BUFFERHEADERTYPE* pHeader = 0; + OMX_DIRTYPE portDir = OMX_DirMax; + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + for (TInt j=0; jIsBufferAtHome(pHeader)) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::InitiateTunnellingDataFlow : BUFFER HEADER[%X] is not at home"), + pHeader); + continue; + } + + portDir = pPort->Direction(); + __ASSERT_DEBUG((OMX_DirInput == portDir || + OMX_DirOutput == portDir), + User::Panic(KOmxILPortManagerPanicCategory, 1)); + + if (OMX_DirInput == portDir) + { + // Input port -> Send buffer to callback manager... + omxRetValue = + iCallbacks.BufferDoneNotification(pHeader, + portIndex, + portDir); + } + else + { + // Output port -> Send buffer to processing function... + omxRetValue = + iProcessingFunction.BufferIndication(pHeader, + portDir); + } + + if (omxRetValue != OMX_ErrorNone) + { + return omxRetValue; + } + + // Inform the port that one of its buffers has been sent + // away... + TBool bufferMarkedWithOwnMark = EFalse; + if (!pPort->SetBufferSent(pHeader, bufferMarkedWithOwnMark)) + { + // The buffer header was not found... + return OMX_ErrorBadParameter; + } + + // For each MarkBuffer command processed, the IL Client must be notified + // with an OMX_EventCommandComplete event... + if (bufferMarkedWithOwnMark) + { + if (OMX_ErrorNone != + (omxRetValue = iCallbacks.CommandCompleteNotification( + OMX_CommandMarkBuffer, portIndex))) + { + return omxRetValue; + } + } + + } // for (TInt j=0; jIsEnabled() && pPort->IsTunnelledAndBufferSupplier()) + + // Increment loop counter + ++i; + } + while(OMX_ALL == aPortIndex && i < portCount); + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::BufferIndication( + OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection, + OMX_BOOL aPortIsDisabled /* = OMX_FALSE */) + { + + OMX_U32 portIndex = aDirection == OMX_DirInput ? + apBufferHeader->nInputPortIndex : apBufferHeader->nOutputPortIndex; + + DEBUG_PRINTF3(_L8("COmxILPortManager::BufferIndication : PORT[%u] BUFFER [%X] "), + portIndex, apBufferHeader); + + // Check the index of the port.. + if (CheckPortIndex(portIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + // Grab the port here... + COmxILPort* pPort = iAllPorts[portIndex]; + + // Check that port direction is the correct one... + if (pPort->Direction() != aDirection) + { + return OMX_ErrorBadPortIndex; + } + +#ifdef _OMXIL_COMMON_IL516C_ON + (void)aPortIsDisabled; + // Only restriction here is that the port must be populated + if (!pPort->IsPopulated()) + { + return OMX_ErrorIncorrectStateOperation; + } +#endif + +#ifndef _OMXIL_COMMON_IL516C_ON + if (!pPort->IsEnabled() && + !pPort->IsTransitioningToDisabled() && + !pPort->IsTransitioningToEnabled()) + { + return OMX_ErrorIncorrectStateOperation; + } + + // Check port enabled property... + if (OMX_TRUE == aPortIsDisabled && + pPort->IsEnabled()) + { + // There is an indication from the FSM that the port must be disabled, + // otherwise, the buffer indication is not allowed in the current + // state. + return OMX_ErrorIncorrectStateOperation; + } + +#endif + + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + // Check whether this port is a buffer supplier... + if (pPort->IsTunnelledAndBufferSupplier() && + pPort->IsTransitioningToDisabled()) + { + // Set the state of the port to disabled as the command has already + // completed... + if (!pPort->SetBufferReturned(apBufferHeader)) + { + // The buffer header was not found... + return OMX_ErrorBadParameter; + } + + if (pPort->HasAllBuffersAtHome()) + { + // All buffers at home.. we can initiate here the + // depopulation of the tunnel... + TBool portDepopulationCompleted = EFalse; + if (OMX_ErrorNone != + (omxRetValue = pPort->FreeTunnel(portDepopulationCompleted))) + { + return omxRetValue; + } + + // Inform the port that the disabled command has + // completed... + pPort->SetTransitionToDisabledCompleted(); + + // For each disabled port, the IL Client must be notified + // with a port disabled completion event... + if (OMX_ErrorNone != + (omxRetValue = iCallbacks.CommandCompleteNotification( + OMX_CommandPortDisable, portIndex))) + { + return omxRetValue; + } + } + + // Make sure the buffer contents are cleared... + TOmxILUtil::ClearBufferContents(apBufferHeader); + + // ... we are done.. no need to send the buffer to the + // processing function... + return OMX_ErrorNone; + + } // if ((pPort->IsTunnelledAndBufferSupplier() && pPort->IsTransitioningToDisabled()) +#ifdef _OMXIL_COMMON_IL516C_ON + else if (pPort->IsTunnelled() && pPort->IsTransitioningToDisabled()) + { + // We get here if the port is tunnelled, non-supplier and is currently + // in the process of transitioning to disabled... To avoid Race + // condition #3, we need to check that we've received the request from + // the supplier to return its buffers... however, we don't check it for + // now, it is just easier to return the buffer now... + DEBUG_PRINTF3(_L8("COmxILPortManager::BufferIndication : PORT [%u] BUFFER [%X] : " + "WARNING This port is being disabled, " + "the buffer id being returned to the tunnelled component"), + portIndex, apBufferHeader); + omxRetValue = + iCallbacks.BufferDoneNotification(apBufferHeader, + portIndex, + aDirection); + // ... we are done.. + return OMX_ErrorNone; + } +#endif + + + // Inform the port that one of its buffers is going to be sent to the + // processing function (exception applies to OMX_PortDomainOther ports) ... + // The port will also mark this buffer if the port + // has pending marks to be signalled... The buffer marks are finally + // processed/propagated by the callback manager once the buffer has been + // consumed by the processing function... + TBool bufferMarkedWithOwnMark = EFalse; + if (!pPort->SetBufferSent(apBufferHeader, bufferMarkedWithOwnMark)) + { + return OMX_ErrorBadParameter; + } + + // For each MarkBuffer command processed, the IL Client must be notified + // with an OMX_EventCommandComplete event... + if (bufferMarkedWithOwnMark) + { + if (OMX_ErrorNone != + (omxRetValue = iCallbacks.CommandCompleteNotification( + OMX_CommandMarkBuffer, portIndex))) + { + return omxRetValue; + } + } + + if (iImmediateReturnTimeBuffer && iTimePorts[portIndex]) + { + // OMX_OTHER_FormatTime ports (such as COmxILClientClockPort) needs + // to return the buffer sooner to the buffer supplier component + OMX_TIME_MEDIATIMETYPE* pMediaTime = + reinterpret_cast(apBufferHeader->pBuffer); + + OMX_TIME_MEDIATIMETYPE timeInfo; + if (pMediaTime) + { + timeInfo = *pMediaTime; + } + + // Return the buffer (send the Buffer Done notification) via callback now. + apBufferHeader->nFilledLen = 0; + + OMX_ERRORTYPE err = iCallbacks.ClockBufferDoneNotification( + apBufferHeader, portIndex, aDirection); + + if (err != OMX_ErrorNone) + { + return err; + } + + if (pMediaTime) + { + // Send time update to the processing function + err = iProcessingFunction.MediaTimeIndication(timeInfo); + } + + __ASSERT_DEBUG(err != OMX_ErrorNotImplemented, + User::Panic(KOmxILPortManagerPanicCategory, 1)); + + return err; + } + + return iProcessingFunction.BufferIndication(apBufferHeader, + aDirection); + } + + +OMX_ERRORTYPE +COmxILPortManager::BufferReturnIndication( + OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection, + TBool& aAllBuffersReturned) + { + + aAllBuffersReturned = EFalse; + + OMX_U32 portIndex = aDirection == OMX_DirInput ? + apBufferHeader->nInputPortIndex : apBufferHeader->nOutputPortIndex; + + DEBUG_PRINTF3(_L8("COmxILPortManager::BufferReturnIndication : PORT[%u] BUFFER [%X]"), + portIndex, apBufferHeader); + + // Check the index of the port.. + if (CheckPortIndex(portIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + // Grab the port here... + COmxILPort* pPort = iAllPorts[portIndex]; + + // Check that port direction is the correct one... + if (pPort->Direction() != aDirection) + { + return OMX_ErrorBadPortIndex; + } + + + if (!pPort->IsEnabled()) + { + return OMX_ErrorBadPortIndex; + } + + // Check that this port must be buffer supplier... + if (!pPort->IsTunnelledAndBufferSupplier()) + { + return OMX_ErrorBadPortIndex; + } + + // Inform the port that a buffer has returned... + if (!pPort->SetBufferReturned(apBufferHeader)) + { + // The buffer header was not found... + return OMX_ErrorBadParameter; + } + + // Make sure the buffer contents are cleared... + TOmxILUtil::ClearBufferContents(apBufferHeader); + + if (pPort->HasAllBuffersAtHome()) + { + aAllBuffersReturned = ETrue; + } + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::BufferFlushIndicationFlushCommand( + TUint32 aPortIndex, TBool aEjectBuffers /* = ETrue */) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::BufferFlushIndicationFlushCommand : PORT[%u]"), aPortIndex); + + // Check the index of the port.. + if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone)) + { + return OMX_ErrorBadPortIndex; + } + + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + RPointerArray portsToFlush; + RPointerArray portsToNotify; + const TInt portCount = iAllPorts.Count(); + COmxILPort* pPort = 0; + TInt i=0; + TBool flushSuccessful; + do + { + flushSuccessful = ETrue; + if (aPortIndex != OMX_ALL) + { + // Grab the port here... + pPort = iAllPorts[aPortIndex]; + } + else + { + pPort = iAllPorts[i]; + } + + if (pPort->IsEnabled() && pPort->Count()) + { + // If port is tunnelled: + // + // - Output ports buffers are sent to the processing function when + // flushed + // + // - Input ports buffers are sent upstream. + // + // If port is non-tunnelled: + // - Buffers are ejected always... + if (pPort->IsTunnelled()) + { + // Remove buffers from PF only... + RemoveBuffersFromPfOrCm(pPort, OMX_TRUE); + + if (aEjectBuffers) + { + // Now we need to send input buffers upstream and ouput + // buffers to the PF... this is done by + // InitiateTunnellingDataFlow + if ((omxRetValue = InitiateTunnellingDataFlow( + pPort->Index(), OMX_TRUE)) != OMX_ErrorNone) + { + // The flush has failed, we need to notify the IL Cient + // via EventHandler... + iCallbacks.ErrorEventNotification(omxRetValue); + flushSuccessful = EFalse; + } + } + } + else + { + // All other ports are simply flushed... + portsToFlush.Append(pPort); + } + } + // Notify flushing completed, even if there was nothing to + // flush... + if (flushSuccessful) + { + portsToNotify.Append(pPort); + } + + // Increment loop counter + ++i; + } + while(OMX_ALL == aPortIndex && i < portCount); + + const TInt flushCount = portsToFlush.Count(); + const TInt notifyCount = portsToNotify.Count(); + + + if (iAllPorts.Count() == flushCount) + { + omxRetValue = iProcessingFunction.BufferFlushingIndication( + OMX_ALL, + OMX_DirMax); + } + else + { + for (i=0; iIndex(), + pPort->Direction()); + } + } + + for (i=0; iIndex()); + } + + portsToFlush.Close(); + portsToNotify.Close(); + + return omxRetValue; + + } + +OMX_ERRORTYPE +COmxILPortManager::BufferFlushIndicationPauseOrExeToIdleCommand( + TBool& aAllBuffersReturnedToSuppliers) + { + DEBUG_PRINTF(_L8("COmxILPortManager::BufferFlushIndicationPauseOrExeToIdleCommand")); + + aAllBuffersReturnedToSuppliers = EFalse; + + const TInt portCount = iAllPorts.Count(); + TBool foundBufferSupplierThatNeedsToWait = EFalse; + COmxILPort* pPort = 0; + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + for (TInt i=0; iCount()) + { + if (pPort->IsTunnelledAndBufferSupplier() && + !pPort->HasAllBuffersAtHome()) + { + if (!RemoveBuffersFromPfOrCm(pPort)) + { + // This port will have to wait to get some of its buffers + // returned by the tunnelled port... + foundBufferSupplierThatNeedsToWait = ETrue; +#ifdef _OMXIL_COMMON_IL516C_ON + // Request buffer ejection from the tunnelled component + iCallbacks.EjectBuffersRequest(pPort->Index()); +#endif + } + continue; + } + +#ifdef _OMXIL_COMMON_IL516C_ON + if (!pPort->IsTunnelled()) + { +#endif + + if (OMX_ErrorNone != + (omxRetValue = iProcessingFunction.BufferFlushingIndication( + pPort->Index(), + pPort->Direction()))) + { + return omxRetValue; + } + +#ifdef _OMXIL_COMMON_IL516C_ON + } +#endif + + } + } + + if (!foundBufferSupplierThatNeedsToWait) + { + aAllBuffersReturnedToSuppliers = ETrue; + } + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::PortEnableIndication( + TUint32 aPortIndex, + TBool aIndicationIsFinal) + { + DEBUG_PRINTF3(_L8("COmxILPortManager::PortEnableIndication: PORT[%u] TRANSITIONISFINAL[%d]"), aPortIndex, aIndicationIsFinal); + + // Check the index of the port.. + if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone)) + { + return OMX_ErrorBadPortIndex; + } + + const TInt portCount = iAllPorts.Count(); + COmxILPort* pPort = 0; + OMX_U32 portIndex = 0; + TInt i=0; + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + do + { + // We do this so we loop or not depending on the needs... + if (aPortIndex != OMX_ALL) + { + // Grab the port here... + pPort = iAllPorts[aPortIndex]; + portIndex = aPortIndex; + } + else + { + pPort = iAllPorts[i]; + portIndex = pPort->Index(); + } + + // If port is already enabled, just indicate that the enable command has + // completed successfully + if (pPort->IsEnabled()) + { + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.CommandCompleteNotification( + OMX_CommandPortEnable, portIndex))) + { + return omxRetValue; + } + + ++i; + continue; + } + + // First check that no-one port is currently transitioning to + // Enabled... + if (pPort->IsTransitioningToEnabled() || + pPort->IsTransitioningToDisabled()) + { + // Send an error event... The spec mandates that the nData2 and + // the pEventData are 0 and NULL respectively, but they could be + // used here to hand some information like the index of the port + // that has failed... + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.ErrorEventNotification(OMX_ErrorPortUnresponsiveDuringAllocation))) + { + return omxRetValue; + } + + if (OMX_ALL == aPortIndex) + { + ++i; + continue; + } + else + { + return OMX_ErrorUndefined; + } + } + + if (aIndicationIsFinal) + { + // Inform the port that it has been enabled.. + pPort->SetTransitionToEnabledCompleted(); + + // For each enabled port, the IL Client must be notified + // with an enabled completion event... + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.CommandCompleteNotification( + OMX_CommandPortEnable, portIndex))) + { + return omxRetValue; + } + + } + else + { + // Inform the port that it is being enabled.. + pPort->SetTransitionToEnabled(); + } + + // Increment loop counter + ++i; + } + while(OMX_ALL == aPortIndex && i < portCount); + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::PortDisableIndication( + TUint32 aPortIndex) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::PortDisableIndication: PORT[%u] "), aPortIndex); + + // Check the index of the port.. + if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone)) + { + return OMX_ErrorBadPortIndex; + } + + const TInt portCount = iAllPorts.Count(); + COmxILPort* pPort = 0; + OMX_U32 portIndex = 0; + TInt i=0; + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + do + { + if (aPortIndex != OMX_ALL) + { + // Grab the port here... + pPort = iAllPorts[aPortIndex]; + portIndex = aPortIndex; + } + else + { + pPort = iAllPorts[i]; + portIndex = pPort->Index(); + } + + // If port is already disabled, just indicate that the disable command has + // completed successfully + if (!pPort->IsEnabled()) + { + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.CommandCompleteNotification( + OMX_CommandPortDisable, portIndex))) + { + return omxRetValue; + } + + ++i; + continue; + } + + // First check that no-one port is currently transitioning to + // Disabled... + if (pPort->IsTransitioningToDisabled() || + pPort->IsTransitioningToEnabled()) + { + // Send an error event... The spec mandates that the nData2 and + // the pEventData are 0 and NULL respectively, but they could be + // used here to hand some information like the index of the port + // that has failed... + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.ErrorEventNotification(OMX_ErrorPortUnresponsiveDuringAllocation))) + { + return omxRetValue; + } + + if (OMX_ALL == aPortIndex) + { + ++i; + continue; + } + else + { + return OMX_ErrorUndefined; + } + + } + + if (pPort->IsTunnelledAndBufferSupplier()) + { + if (!pPort->HasAllBuffersAtHome() && !RemoveBuffersFromPfOrCm(pPort)) + { + // Inform the port that it is being disabled + pPort->SetTransitionToDisabled(); + // This port will have to wait to get all its buffers + // returned by the tunnelled port... +#ifdef _OMXIL_COMMON_IL516C_ON + //... but request the ejection of the buffers first... + iCallbacks.EjectBuffersRequest(pPort->Index()); +#endif + } + else + { + // Buffer supplier with all buffers at home.. we can + // initiate here the depopulation of the tunnel... + + // This boolean is not used here ... + TBool portDepopulationCompleted = EFalse; + + // Better to ignore here any possible error in + // FreeTunnel... nothing we can do about it... + if (OMX_ErrorNone != + (omxRetValue = + pPort->FreeTunnel(portDepopulationCompleted))) + { + return omxRetValue; + } + + // Inform the port that the disabled command has + // completed... + pPort->SetTransitionToDisabledCompleted(); + + // For each disabled port, the IL Client must be notified + // with a disabled completion event... + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.CommandCompleteNotification( + OMX_CommandPortDisable, portIndex))) + { + return omxRetValue; + } + + } // else <- if (!pPort->HasAllBuffersAtHome()) + + } // if (pPort->IsTunnelledAndBufferSupplier()) + else + { + if (pPort->Count() > 0) + { + +#ifdef _OMXIL_COMMON_IL516C_ON + if (!pPort->IsTunnelled()) + { +#endif + + if (OMX_ErrorNone != + (omxRetValue = + iProcessingFunction.BufferFlushingIndication( + portIndex, + pPort->Direction()))) + { + return omxRetValue; + } + +#ifdef _OMXIL_COMMON_IL516C_ON + } +#endif + + // Inform the port that it is being disabled + pPort->SetTransitionToDisabled(); + } + else + { + // Inform the port that the disabled command has + // completed... + pPort->SetTransitionToDisabledCompleted(); + + // For each disabled port, the IL Client must be notified + // with a disabled completion event... + if (OMX_ErrorNone != + (omxRetValue = + iCallbacks.CommandCompleteNotification( + OMX_CommandPortDisable, portIndex))) + { + return omxRetValue; + } + } + + } + + // Increment loop counter + ++i; + } + while(OMX_ALL == aPortIndex && i < portCount); + + return OMX_ErrorNone; + + } + +OMX_ERRORTYPE +COmxILPortManager::BufferMarkIndication( + TUint32 aPortIndex, + OMX_PTR ipMarkData) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::BufferMarkIndication: PORT[%u] "), aPortIndex); + + // Check the index of the port.. + if (CheckPortIndex(aPortIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + const OMX_MARKTYPE* pMark = static_cast(ipMarkData); + + if (!pMark->hMarkTargetComponent) + { + return OMX_ErrorBadParameter; + } + + // Let's tell the port to store the mark so it can mark the next incoming + // buffer... + return iAllPorts[aPortIndex]->StoreBufferMark(pMark); + + } + +#ifdef _OMXIL_COMMON_IL516C_ON +OMX_ERRORTYPE +COmxILPortManager::BufferEjectIndication( + TUint32 aPortIndex) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::BufferEjectIndication: PORT[%u] "), aPortIndex); + + // Check the index of the port.. + if (CheckPortIndex(aPortIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + COmxILPort* pPort = iAllPorts[aPortIndex]; + + if (pPort->Count()) + { + omxRetValue = iProcessingFunction.BufferFlushingIndication( + pPort->Index(), + pPort->Direction()); + } + + return omxRetValue; + + } +#endif + +OMX_ERRORTYPE +COmxILPortManager::ComponentRoleIndication(TUint aComponentRoleIndex) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::ComponentRoleIndication : aComponentRoleIndex[%u]"), aComponentRoleIndex); + + // At this point, the IL Client wants to set the default role that the + // standard component is assuming. Therefore, the role defaults need to be + // reloaded into all ports and the processing function object. + OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; + const TInt portCount = iAllPorts.Count(); + for (TUint i = 0; i< portCount; ++i) + { + if (OMX_ErrorNone != + (omxRetValue = + iAllPorts[i]->SetComponentRoleDefaults(aComponentRoleIndex))) + { + return omxRetValue; + } + } + + return iProcessingFunction.ComponentRoleIndication(aComponentRoleIndex); + + } + +OMX_ERRORTYPE +COmxILPortManager::PortSettingsChangeIndication(OMX_U32 aPortIndex, + TUint aPortSettingsIndex, + const TDesC8& aPortSettings, + OMX_EVENTTYPE& aEventForILClient) + { + DEBUG_PRINTF2(_L8("COmxILPortManager::PortSettingsChangeIndication: PORT[%u] "), aPortIndex); + + // Check the index of the port.. + if (CheckPortIndex(aPortIndex) != OMX_ErrorNone) + { + return OMX_ErrorBadPortIndex; + } + + return iAllPorts[aPortIndex]->DoPortReconfiguration( + aPortSettingsIndex, aPortSettings, aEventForILClient); + + } + + +TBool +COmxILPortManager::AllPortsPopulated() const + { + + const TInt portCount = iAllPorts.Count(); + COmxILPort* pPort = 0; + for (TInt i=0; iIsEnabled()) + { + continue; + } + + if (!pPort->IsPopulated()) + { + DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsPopulated : [FALSE]")); + return EFalse; + } + } + + DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsPopulated : [TRUE]")); + return ETrue; + + } + +TBool +COmxILPortManager::AllPortsDePopulated() const + { + + const TInt portCount = iAllPorts.Count(); + for (TInt i=0; iIsDePopulated()) + { + DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsDePopulated : [FALSE]")); + return EFalse; + } + } + + DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsDePopulated : [TRUE]")); + return ETrue; + + } + +TBool +COmxILPortManager::AllBuffersAtHome() const + { + + const TInt portCount = iAllPorts.Count(); + for (TInt i=0; iIsTunnelledAndBufferSupplier()) + { + if (!iAllPorts[i]->HasAllBuffersAtHome()) + { + DEBUG_PRINTF(_L8("COmxILPortManager::AllBuffersAtHome : [FALSE]")); + return EFalse; + } + } + } + + DEBUG_PRINTF(_L8("COmxILPortManager::AllBuffersAtHome : [TRUE]")); + return ETrue; + + }