--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omxil/omxilcomponentcommon/src/common/omxilportmanager.cpp Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,1953 @@
+// 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 "omxilprocessingfunction.h"
+#include "omxilcallbackmanager.h"
+#include "omxilutil.h"
+
+EXPORT_C 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,
+ aOmxVersion,
+ aNumberOfAudioPorts,
+ aStartAudioPortNumber,
+ aNumberOfImagePorts,
+ aStartImagePortNumber,
+ aNumberOfVideoPorts,
+ aStartVideoPortNumber,
+ aNumberOfOtherPorts,
+ aStartOtherPortNumber,
+ aImmediateReturnTimeBuffer);
+
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void
+COmxILPortManager::ConstructL()
+ {
+ DEBUG_PRINTF(_L8("COmxILPortManager::ConstructL"));
+
+ 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,
+ 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)
+ :
+ iProcessingFunction(aProcessingFunction),
+ iCallbacks(aCallbacks),
+ iAllPorts(),
+ iImmediateReturnTimeBuffer(aImmediateReturnTimeBuffer)
+ {
+ DEBUG_PRINTF(_L8("COmxILPortManager::COmxILPortManager"));
+
+ 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;
+
+ }
+
+COmxILPortManager::~COmxILPortManager()
+ {
+ DEBUG_PRINTF(_L8("COmxILPortManager::~COmxILPortManager"));
+ iAllPorts.Reset(); // data not owned here
+ 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; i<portCount; ++i)
+ {
+ if (iAllPorts[i]->Index() >= aPort->Index())
+ {
+ User::Panic(KOmxILPortManagerPanicCategory, 1);
+ }
+ }
+ iAllPorts.AppendL(aPort);
+ }
+
+ iTimePorts.AppendL(timePort);
+ }
+
+/**
+ 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.
+*/
+EXPORT_C 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;
+ }
+
+ TRAPD(err, AppendPortL(aPort));
+ if (KErrNone != err)
+ {
+ return err;
+ }
+
+ 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;
+ }
+ }
+
+ // 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)
+ {
+ 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; j<headerCount; ++j)
+ {
+ pHeader = (*apPort)[j];
+ if (!apPort->IsBufferAtHome(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<OMX_PTR>(apComponentParameterStructure),
+ sizeof(OMX_PORT_PARAM_TYPE))))
+ {
+ return omxRetValue;
+ }
+
+ OMX_PORT_PARAM_TYPE*
+ pPortParamType
+ = static_cast<OMX_PORT_PARAM_TYPE*>(
+ 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;
+ }
+
+ // 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"));
+
+ 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;
+ }
+
+ 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];
+
+ 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;
+ }
+
+ // 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_PRINTF2(_L8("COmxILPortManager::FreeBuffer : BUFFER [%X]"), 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; i<portCount; ++i)
+ {
+ pPort = iAllPorts[i];
+ if (pPort->IsEnabled() && 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 */)
+ {
+ 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() && 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; j<headerCount; ++j)
+ {
+ // Here, there are two options:
+ //
+ // 1. -The port is an input port, in which case, the buffer is
+ // directly sent to the callback manager which in turn sends it
+ // to the tunnelled component in charge of filling it
+ // (OMX_FillThisBuffer)
+ //
+ // 2.- The port is an output port, and the buffer must be sent
+ // to the processing function to be filled before the buffer
+ // can be sent to the tunnelled component. After that, the proc
+ // function will send the buffer to the call back manager to be
+ // sent to the tunnelled component (OMX_EmptyThisBuffer)...
+ pHeader = (*pPort)[j];
+
+ // Check that we actually have the buffer in our side...
+ if (!pPort->IsBufferAtHome(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; j<headerCount; j++)
+ } // if (pPort->IsEnabled() && 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 */)
+ {
+ DEBUG_PRINTF2(_L8("COmxILPortManager::BufferIndication : BUFFER [%X]"), apBufferHeader);
+
+ OMX_U32 portIndex = aDirection == OMX_DirInput ?
+ apBufferHeader->nInputPortIndex : apBufferHeader->nOutputPortIndex;
+
+ // 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() &&
+ !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;
+ }
+
+ 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->IsTransitioningToDisabled())
+
+
+ // 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<OMX_TIME_MEDIATIMETYPE*>(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)
+ {
+ DEBUG_PRINTF2(_L8("COmxILPortManager::BufferReturnIndication : [%X]"), apBufferHeader);
+
+ aAllBuffersReturned = EFalse;
+
+ OMX_U32 portIndex = aDirection == OMX_DirInput ?
+ apBufferHeader->nInputPortIndex : apBufferHeader->nOutputPortIndex;
+
+ // 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[%d]"), aPortIndex);
+
+ // Check the index of the port..
+ if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone))
+ {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
+ RPointerArray<COmxILPort> portsToFlush;
+ RPointerArray<COmxILPort> 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 (pPort->IsTunnelledAndBufferSupplier() &&
+ !pPort->HasAllBuffersAtHome())
+ {
+ // 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...
+ if ((omxRetValue = InitiateTunnellingDataFlow())
+ != OMX_ErrorNone)
+ {
+ // The flush has failed, we need to notify the IL Cient
+ // via EventHandler...
+ iCallbacks.ErrorEventNotification(omxRetValue);
+ flushSuccessful = EFalse;
+ }
+ }
+
+ }
+ else
+ {
+ 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; i<flushCount && OMX_ErrorNone == omxRetValue; ++i)
+ {
+ pPort = portsToFlush[i];
+ omxRetValue = iProcessingFunction.BufferFlushingIndication(
+ pPort->Index(),
+ pPort->Direction());
+ }
+ }
+
+ for (i=0; i<notifyCount && OMX_ErrorNone == omxRetValue; ++i)
+ {
+ pPort = portsToNotify[i];
+ omxRetValue = iCallbacks.CommandCompleteNotification(OMX_CommandFlush,
+ portsToNotify[i]->Index());
+ }
+
+ 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; i<portCount; ++i)
+ {
+ pPort = iAllPorts[i];
+
+ if (pPort->IsEnabled() && pPort->Count())
+ {
+ 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;
+ }
+ continue;
+ }
+
+ if (OMX_ErrorNone !=
+ (omxRetValue = iProcessingFunction.BufferFlushingIndication(
+ pPort->Index(),
+ pPort->Direction())))
+ {
+ return omxRetValue;
+ }
+ }
+ }
+
+ if (!foundBufferSupplierThatNeedsToWait)
+ {
+ aAllBuffersReturnedToSuppliers = ETrue;
+ }
+
+ return OMX_ErrorNone;
+
+ }
+
+OMX_ERRORTYPE
+COmxILPortManager::PortEnableIndication(
+ TUint32 aPortIndex,
+ TBool aIndicationIsFinal)
+ {
+ DEBUG_PRINTF3(_L8("COmxILPortManager::PortEnableIndication: PORT[%d] 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[%d] "), 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...
+ }
+ 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)
+ {
+ if (OMX_ErrorNone !=
+ (omxRetValue =
+ iProcessingFunction.BufferFlushingIndication(
+ portIndex,
+ pPort->Direction())))
+ {
+ return omxRetValue;
+ }
+
+ // 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[%d] "), aPortIndex);
+
+ // Check the index of the port..
+ if (CheckPortIndex(aPortIndex) != OMX_ErrorNone)
+ {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ const OMX_MARKTYPE* pMark = static_cast<OMX_MARKTYPE*>(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);
+
+ }
+
+OMX_ERRORTYPE
+COmxILPortManager::ComponentRoleIndication(TUint aComponentRoleIndex)
+ {
+ DEBUG_PRINTF2(_L8("COmxILPortManager::ComponentRoleIndication : aComponentRoleIndex[%d]"), 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[%d] "), 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; i<portCount; ++i)
+ {
+ pPort = iAllPorts[i];
+ if (!pPort->IsEnabled())
+ {
+ 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; i<portCount; ++i)
+ {
+ if (!iAllPorts[i]->IsDePopulated())
+ {
+ 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; i<portCount; ++i)
+ {
+ if (iAllPorts[i]->IsTunnelledAndBufferSupplier())
+ {
+ if (!iAllPorts[i]->HasAllBuffersAtHome())
+ {
+ DEBUG_PRINTF(_L8("COmxILPortManager::AllBuffersAtHome : [FALSE]"));
+ return EFalse;
+ }
+ }
+ }
+
+ DEBUG_PRINTF(_L8("COmxILPortManager::AllBuffersAtHome : [TRUE]"));
+ return ETrue;
+
+ }