omxil/omxilcomponentcommon/src/common/omxilportmanager.cpp
changeset 56 b6488ac24ddc
parent 47 481b3bce574a
child 57 1cbb0d5bf7f2
equal deleted inserted replaced
47:481b3bce574a 56:b6488ac24ddc
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 /**
       
    18  @file
       
    19  @internalComponent
       
    20 */
       
    21 
       
    22 #include "log.h"
       
    23 #include "omxilportmanager.h"
       
    24 #include "omxilprocessingfunction.h"
       
    25 #include "omxilcallbackmanager.h"
       
    26 #include "omxilutil.h"
       
    27 
       
    28 EXPORT_C COmxILPortManager*
       
    29 COmxILPortManager::NewL(
       
    30 	COmxILProcessingFunction& aProcessingFunction,
       
    31 	MOmxILCallbackManagerIf& aCallbacks,
       
    32 	const OMX_VERSIONTYPE& aOmxVersion,
       
    33 	OMX_U32 aNumberOfAudioPorts,
       
    34 	OMX_U32 aStartAudioPortNumber,
       
    35 	OMX_U32 aNumberOfImagePorts,
       
    36 	OMX_U32 aStartImagePortNumber,
       
    37 	OMX_U32 aNumberOfVideoPorts,
       
    38 	OMX_U32 aStartVideoPortNumber,
       
    39 	OMX_U32 aNumberOfOtherPorts,
       
    40 	OMX_U32 aStartOtherPortNumber,
       
    41 	OMX_BOOL aImmediateReturnTimeBuffer)
       
    42 	{
       
    43     DEBUG_PRINTF(_L8("COmxILPortManager::NewL"));
       
    44 
       
    45 	COmxILPortManager* self =
       
    46 		new (ELeave)COmxILPortManager(
       
    47 			aProcessingFunction,
       
    48 			aCallbacks,
       
    49 			aOmxVersion,
       
    50 			aNumberOfAudioPorts,
       
    51 			aStartAudioPortNumber,
       
    52 			aNumberOfImagePorts,
       
    53 			aStartImagePortNumber,
       
    54 			aNumberOfVideoPorts,
       
    55 			aStartVideoPortNumber,
       
    56 			aNumberOfOtherPorts,
       
    57 			aStartOtherPortNumber,
       
    58 			aImmediateReturnTimeBuffer);
       
    59 
       
    60 	CleanupStack::PushL(self);
       
    61 	self->ConstructL();
       
    62 	CleanupStack::Pop(self);
       
    63 	return self;
       
    64 	}
       
    65 
       
    66 void
       
    67 COmxILPortManager::ConstructL()
       
    68 	{
       
    69     DEBUG_PRINTF(_L8("COmxILPortManager::ConstructL"));
       
    70 
       
    71 	InsertParamIndexL(OMX_IndexParamAudioInit);
       
    72 	InsertParamIndexL(OMX_IndexParamImageInit);
       
    73 	InsertParamIndexL(OMX_IndexParamVideoInit);
       
    74 	InsertParamIndexL(OMX_IndexParamOtherInit);
       
    75 
       
    76 
       
    77 	if(iAudioParamInit.nStartPortNumber != 0)
       
    78 		{
       
    79 		User::Leave(KErrArgument);
       
    80 		}
       
    81 
       
    82 	if (iImageParamInit.nPorts > 0)
       
    83 		{
       
    84 		if (iAudioParamInit.nPorts !=
       
    85 			iImageParamInit.nStartPortNumber)
       
    86 			{
       
    87 			User::Leave(KErrArgument);
       
    88 			}
       
    89 		}
       
    90 
       
    91 	if (iVideoParamInit.nPorts > 0)
       
    92 		{
       
    93 		if ((iAudioParamInit.nPorts +
       
    94 			 iImageParamInit.nPorts)  !=
       
    95 			iVideoParamInit.nStartPortNumber)
       
    96 			{
       
    97 			User::Leave(KErrArgument);
       
    98 			}
       
    99 		}
       
   100 
       
   101 	if (iOtherParamInit.nPorts > 0)
       
   102 		{
       
   103 		if ((iAudioParamInit.nPorts +
       
   104 			 iImageParamInit.nPorts +
       
   105 			 iVideoParamInit.nPorts)  !=
       
   106 			iOtherParamInit.nStartPortNumber)
       
   107 			{
       
   108 			User::Leave(KErrArgument);
       
   109 			}
       
   110 		}
       
   111 
       
   112 	}
       
   113 
       
   114 COmxILPortManager::COmxILPortManager(
       
   115 	COmxILProcessingFunction& aProcessingFunction,
       
   116 	MOmxILCallbackManagerIf& aCallbacks,
       
   117 	const OMX_VERSIONTYPE& aOmxVersion,
       
   118 	OMX_U32 aNumberOfAudioPorts,
       
   119 	OMX_U32 aStartAudioPortNumber,
       
   120 	OMX_U32 aNumberOfImagePorts,
       
   121 	OMX_U32 aStartImagePortNumber,
       
   122 	OMX_U32 aNumberOfVideoPorts,
       
   123 	OMX_U32 aStartVideoPortNumber,
       
   124 	OMX_U32 aNumberOfOtherPorts,
       
   125 	OMX_U32 aStartOtherPortNumber,
       
   126 	OMX_BOOL aImmediateReturnTimeBuffer)
       
   127 	:
       
   128 	iProcessingFunction(aProcessingFunction),
       
   129 	iCallbacks(aCallbacks),
       
   130 	iAllPorts(),
       
   131 	iImmediateReturnTimeBuffer(aImmediateReturnTimeBuffer)
       
   132 	{
       
   133     DEBUG_PRINTF(_L8("COmxILPortManager::COmxILPortManager"));
       
   134 
       
   135 	iAudioParamInit.nSize			 = sizeof(OMX_PORT_PARAM_TYPE);
       
   136 	iAudioParamInit.nVersion		 = aOmxVersion;
       
   137 	iAudioParamInit.nPorts			 = aNumberOfAudioPorts;
       
   138 	iAudioParamInit.nStartPortNumber = aStartAudioPortNumber;
       
   139 
       
   140 	iImageParamInit.nSize			 = sizeof(OMX_PORT_PARAM_TYPE);
       
   141 	iImageParamInit.nVersion		 = aOmxVersion;
       
   142 	iImageParamInit.nPorts			 = aNumberOfImagePorts;
       
   143 	iImageParamInit.nStartPortNumber = aStartImagePortNumber;
       
   144 
       
   145 	iVideoParamInit.nSize			 = sizeof(OMX_PORT_PARAM_TYPE);
       
   146 	iVideoParamInit.nVersion		 = aOmxVersion;
       
   147 	iVideoParamInit.nPorts			 = aNumberOfVideoPorts;
       
   148 	iVideoParamInit.nStartPortNumber = aStartVideoPortNumber;
       
   149 
       
   150 	iOtherParamInit.nSize			 = sizeof(OMX_PORT_PARAM_TYPE);
       
   151 	iOtherParamInit.nVersion		 = aOmxVersion;
       
   152 	iOtherParamInit.nPorts			 = aNumberOfOtherPorts;
       
   153 	iOtherParamInit.nStartPortNumber = aStartOtherPortNumber;
       
   154 
       
   155 	}
       
   156 
       
   157 COmxILPortManager::~COmxILPortManager()
       
   158 	{
       
   159     DEBUG_PRINTF(_L8("COmxILPortManager::~COmxILPortManager"));
       
   160 	iAllPorts.Reset(); // data not owned here
       
   161 	iTimePorts.Close();
       
   162 	}
       
   163 
       
   164 void
       
   165 COmxILPortManager::AppendPortL(const COmxILPort* aPort)
       
   166 	{
       
   167     DEBUG_PRINTF(_L8("COmxILPortManager::AppendPort"));
       
   168 
       
   169 	const TInt portCount = iAllPorts.Count();
       
   170 	OMX_PORTDOMAINTYPE portDomain = aPort->Domain();
       
   171 	OMX_U32 startPortNumber = 0;
       
   172 	TBool timePort = EFalse;
       
   173 	
       
   174 	switch(portDomain)
       
   175 		{
       
   176 	case OMX_PortDomainAudio:
       
   177 		{
       
   178 		__ASSERT_ALWAYS(portCount >= 0,
       
   179 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   180 		__ASSERT_ALWAYS(portCount < iAudioParamInit.nPorts,
       
   181 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   182 
       
   183 		startPortNumber = iAudioParamInit.nStartPortNumber;
       
   184 
       
   185 		}
       
   186 		break;
       
   187 
       
   188 	case OMX_PortDomainImage:
       
   189 		{
       
   190 		__ASSERT_ALWAYS(portCount >= iAudioParamInit.nPorts,
       
   191 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   192 		__ASSERT_ALWAYS(portCount <
       
   193 						iAudioParamInit.nPorts +
       
   194 						iImageParamInit.nPorts,
       
   195 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   196 
       
   197 		startPortNumber = iImageParamInit.nStartPortNumber;
       
   198 
       
   199 		}
       
   200 		break;
       
   201 
       
   202 	case OMX_PortDomainVideo:
       
   203 		{
       
   204 		__ASSERT_ALWAYS(portCount >=
       
   205 						iAudioParamInit.nPorts +
       
   206 						iImageParamInit.nPorts,
       
   207 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   208 		__ASSERT_ALWAYS(portCount <
       
   209 						iAudioParamInit.nPorts +
       
   210 						iImageParamInit.nPorts +
       
   211 						iVideoParamInit.nPorts,
       
   212 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   213 
       
   214 		startPortNumber = iVideoParamInit.nStartPortNumber;
       
   215 
       
   216 		}
       
   217 		break;
       
   218 
       
   219 
       
   220 	case OMX_PortDomainOther:
       
   221 		{
       
   222 		__ASSERT_ALWAYS(portCount >=
       
   223 						iAudioParamInit.nPorts +
       
   224 						iImageParamInit.nPorts +
       
   225 						iVideoParamInit.nPorts,
       
   226 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   227 		__ASSERT_ALWAYS(portCount <
       
   228 						iAudioParamInit.nPorts +
       
   229 						iImageParamInit.nPorts +
       
   230 						iVideoParamInit.nPorts +
       
   231 						iOtherParamInit.nPorts,
       
   232 						User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   233 
       
   234 		startPortNumber = iOtherParamInit.nStartPortNumber;
       
   235 		
       
   236 		OMX_OTHER_PARAM_PORTFORMATTYPE paramFormat;
       
   237 		paramFormat.nSize = sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE);
       
   238 		paramFormat.nVersion = TOmxILSpecVersion();
       
   239 		paramFormat.nPortIndex = aPort->Index();
       
   240 		paramFormat.nIndex = 0;
       
   241 
       
   242 		if ((aPort->GetParameter(OMX_IndexParamOtherPortFormat, &paramFormat) == OMX_ErrorNone) &&
       
   243 			paramFormat.eFormat == OMX_OTHER_FormatTime)
       
   244 			{
       
   245 			timePort = ETrue;	
       
   246 			}
       
   247 		}
       
   248 		
       
   249 		break;
       
   250 
       
   251 	default:
       
   252 		{
       
   253 		User::Panic(KOmxILPortManagerPanicCategory, 1);
       
   254 		}
       
   255 		};
       
   256 
       
   257 	if(portCount ==  startPortNumber)
       
   258 		{
       
   259 		iAllPorts.AppendL(aPort);
       
   260 		}
       
   261 	else
       
   262 		{
       
   263 		for (TInt i=startPortNumber; i<portCount; ++i)
       
   264 			{
       
   265 			if (iAllPorts[i]->Index() >= aPort->Index())
       
   266 				{
       
   267 				User::Panic(KOmxILPortManagerPanicCategory, 1);
       
   268 				}
       
   269 			}
       
   270 		iAllPorts.AppendL(aPort);
       
   271 		}
       
   272 
       
   273 	iTimePorts.AppendL(timePort);
       
   274 	}
       
   275 
       
   276 /**
       
   277   This method is used at component's construction time, i.e., in a factory
       
   278   method of the component. The main component object uses this method to add
       
   279   the component's ports to its port manager instance.
       
   280 
       
   281    @param aPort The port instance to be added.
       
   282 
       
   283    @param aDirection The direction of the port being added.
       
   284 
       
   285    @ return A Symbian error code indicating if the function call was
       
   286    successful.  KErrNone on success, otherwise another of the system-wide error
       
   287    codes.
       
   288 */
       
   289 EXPORT_C TInt
       
   290 COmxILPortManager::AddPort(const COmxILPort* aPort,
       
   291 						   OMX_DIRTYPE aDirection)
       
   292 	{
       
   293     DEBUG_PRINTF(_L8("COmxILPortManager::AddPort"));
       
   294 
       
   295 	__ASSERT_ALWAYS(aPort, User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   296 
       
   297 	if (iAllPorts.Count() >= (iAudioParamInit.nPorts +
       
   298 							  iVideoParamInit.nPorts +
       
   299 							  iImageParamInit.nPorts +
       
   300 							  iOtherParamInit.nPorts))
       
   301 		{
       
   302 		return KErrArgument;
       
   303 		}
       
   304 
       
   305 	if (aPort->Direction() != aDirection)
       
   306 		{
       
   307 		return KErrArgument;
       
   308 		}
       
   309 
       
   310 	if (iAllPorts.Find(aPort) != KErrNotFound)
       
   311 		{
       
   312 		return KErrArgument;
       
   313 		}
       
   314 
       
   315 	TRAPD(err, AppendPortL(aPort));
       
   316 	if (KErrNone != err)
       
   317 		{
       
   318 		return err;
       
   319 		}
       
   320 
       
   321 	OMX_ERRORTYPE omxRetValue =
       
   322 		aPort->GetLocalOmxParamIndexes(ManagedParamIndexes());
       
   323 	if (OMX_ErrorNone == omxRetValue)
       
   324 		{
       
   325 		omxRetValue = aPort->GetLocalOmxConfigIndexes(ManagedConfigIndexes());
       
   326 		}
       
   327 
       
   328 	if (OMX_ErrorNone != omxRetValue)
       
   329 		{
       
   330 		if (OMX_ErrorInsufficientResources == omxRetValue)
       
   331 			{
       
   332 			return KErrNoMemory;
       
   333 			}
       
   334 		else
       
   335 			{
       
   336 			return KErrGeneral;
       
   337 			}
       
   338 		}
       
   339 
       
   340 	// Here, let's register this port into the call back manager so buffer
       
   341 	// marks can be propagated to the right port...
       
   342 	const OMX_U32 propagationPortIndex = aPort->BufferMarkPropagationPort();
       
   343 	if (propagationPortIndex != COmxILPort::KBufferMarkPropagationPortNotNeeded)
       
   344 		{
       
   345 		omxRetValue = iCallbacks.RegisterBufferMarkPropagationPort(aPort->Index(),
       
   346 													 propagationPortIndex);
       
   347 		}
       
   348 
       
   349 	err = KErrNone;
       
   350 	if (OMX_ErrorNone != omxRetValue)
       
   351 		{
       
   352 		switch (omxRetValue)
       
   353 				{
       
   354 			case OMX_ErrorInsufficientResources:
       
   355 				{
       
   356 				err = KErrNoMemory;
       
   357 				}
       
   358 				break;
       
   359 			default:
       
   360 				{
       
   361 				err = KErrGeneral;
       
   362 				}
       
   363 				};
       
   364 		}
       
   365 
       
   366 	return err;
       
   367 
       
   368 	}
       
   369 
       
   370 TBool
       
   371 COmxILPortManager::RemoveBuffersFromPfOrCm(
       
   372 	COmxILPort* apPort, OMX_BOOL aRemoveFromPfOnly /* = OMX_FALSE */) const
       
   373 	{
       
   374 	__ASSERT_DEBUG(apPort, User::Panic(KOmxILPortManagerPanicCategory, 1));
       
   375     DEBUG_PRINTF3(_L8("COmxILPortManager::RemoveBuffersFromPfOrCm: PORT[%d] aRemoveFromPfOnly[%s] "),
       
   376 				  apPort->Index(), aRemoveFromPfOnly ? "TRUE" : "FALSE");
       
   377 
       
   378 	const TInt headerCount = apPort->Count();
       
   379 	OMX_BUFFERHEADERTYPE* pHeader = 0;
       
   380 	TBool allHeadersRemovedFromPf = ETrue;
       
   381 	for (TInt j=0; j<headerCount; ++j)
       
   382 		{
       
   383 		pHeader = (*apPort)[j];
       
   384 		if (!apPort->IsBufferAtHome(pHeader))
       
   385 			{
       
   386 			// Tell the PF to remove this header from its queues...
       
   387 			if (!iProcessingFunction.BufferRemovalIndication(
       
   388 					pHeader,
       
   389 					apPort->Direction()))
       
   390 				{
       
   391 				if (OMX_FALSE == aRemoveFromPfOnly)
       
   392 					{
       
   393 					if (!iCallbacks.BufferRemovalIndication(
       
   394 							pHeader,
       
   395 							apPort->Direction()))
       
   396 						{
       
   397 						allHeadersRemovedFromPf = EFalse;
       
   398 						}
       
   399 					else
       
   400 						{
       
   401 						apPort->SetBufferReturned(pHeader);
       
   402 						// Make sure the buffer contents are cleared
       
   403 						TOmxILUtil::ClearBufferContents(pHeader);
       
   404 						}
       
   405 					}
       
   406 				}
       
   407 			else
       
   408 				{
       
   409 				apPort->SetBufferReturned(pHeader);
       
   410 				// Make sure the buffer contents are cleared
       
   411 				TOmxILUtil::ClearBufferContents(pHeader);
       
   412 				}
       
   413 			}
       
   414 		}
       
   415 
       
   416 	return allHeadersRemovedFromPf;
       
   417 
       
   418 	}
       
   419 
       
   420 OMX_ERRORTYPE
       
   421 COmxILPortManager::GetParameter(OMX_INDEXTYPE aParamIndex,
       
   422 								TAny* apComponentParameterStructure) const
       
   423 	{
       
   424     DEBUG_PRINTF(_L8("COmxILPortManager::GetParameter"));
       
   425 
       
   426 	TInt index = FindParamIndex(aParamIndex);
       
   427 	if (KErrNotFound == index)
       
   428 		{
       
   429 		return OMX_ErrorUnsupportedIndex;
       
   430 		}
       
   431 
       
   432 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   433 	switch(aParamIndex)
       
   434 		{
       
   435 	case OMX_IndexParamAudioInit:
       
   436 	case OMX_IndexParamImageInit:
       
   437 	case OMX_IndexParamVideoInit:
       
   438 	case OMX_IndexParamOtherInit:
       
   439 		{
       
   440 		if (OMX_ErrorNone !=
       
   441 			(omxRetValue =
       
   442 			 TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   443 				 const_cast<OMX_PTR>(apComponentParameterStructure),
       
   444 				 sizeof(OMX_PORT_PARAM_TYPE))))
       
   445 			{
       
   446 			return omxRetValue;
       
   447 			}
       
   448 
       
   449 		OMX_PORT_PARAM_TYPE*
       
   450 			pPortParamType
       
   451 			= static_cast<OMX_PORT_PARAM_TYPE*>(
       
   452 				apComponentParameterStructure);
       
   453 
       
   454 		switch(aParamIndex)
       
   455 			{
       
   456 		case OMX_IndexParamAudioInit:
       
   457 			*pPortParamType = iAudioParamInit;
       
   458 			break;
       
   459 		case OMX_IndexParamImageInit:
       
   460 			*pPortParamType = iImageParamInit;
       
   461 			break;
       
   462 		case OMX_IndexParamVideoInit:
       
   463 			*pPortParamType = iVideoParamInit;
       
   464 			break;
       
   465 		case OMX_IndexParamOtherInit:
       
   466 			*pPortParamType = iOtherParamInit;
       
   467 			break;
       
   468 			}
       
   469 
       
   470 		}
       
   471 		break;
       
   472 
       
   473 	default:
       
   474 		{
       
   475 		// Obtain the port index
       
   476 		OMX_U32 portIndex;
       
   477 		if (OMX_ErrorNone != GetPortIndexFromOmxStruct(
       
   478 				apComponentParameterStructure,
       
   479 				portIndex))
       
   480 			{
       
   481 			return OMX_ErrorBadPortIndex;
       
   482 			}
       
   483 
       
   484 		// Now delegate to the specific port
       
   485 		return iAllPorts[portIndex]->GetParameter(
       
   486 			aParamIndex,
       
   487 			apComponentParameterStructure);
       
   488 		}
       
   489 		};
       
   490 
       
   491 	return OMX_ErrorNone;
       
   492 
       
   493 	}
       
   494 
       
   495 OMX_ERRORTYPE
       
   496 COmxILPortManager::SetParameter(OMX_INDEXTYPE aParamIndex,
       
   497 								const TAny* apComponentParameterStructure,
       
   498 								OMX_BOOL aPortIsDisabled /* = OMX_FALSE */ )
       
   499 	{
       
   500     DEBUG_PRINTF(_L8("COmxILPortManager::SetParameter"));
       
   501 
       
   502 	TInt index = FindParamIndex(aParamIndex);
       
   503 	if (KErrNotFound == index)
       
   504 		{
       
   505 		return OMX_ErrorUnsupportedIndex;
       
   506 		}
       
   507 
       
   508 	// Obtain the port index
       
   509 	OMX_U32 portIndex;
       
   510 	if (OMX_ErrorNone != GetPortIndexFromOmxStruct(
       
   511 			apComponentParameterStructure,
       
   512 			portIndex))
       
   513 		{
       
   514 		return OMX_ErrorBadPortIndex;
       
   515 		}
       
   516 
       
   517 	// Grab the port here...
       
   518 	COmxILPort* pPort = iAllPorts[portIndex];
       
   519 
       
   520 	if (OMX_TRUE == aPortIsDisabled &&
       
   521 		pPort->IsEnabled() &&
       
   522 		!pPort->IsTransitioningToEnabled())
       
   523 		{
       
   524 		// There is an indication from the FSM that the port must be disabled,
       
   525 		// otherwise, this is not allowed in the current state.
       
   526 		return OMX_ErrorIncorrectStateOperation;
       
   527 		}
       
   528 
       
   529 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   530 	switch(aParamIndex)
       
   531 		{
       
   532 	case OMX_IndexParamAudioInit:
       
   533 	case OMX_IndexParamVideoInit:
       
   534 	case OMX_IndexParamImageInit:
       
   535 	case OMX_IndexParamOtherInit:
       
   536 		{
       
   537 		// Don't allow changes in the OMX_PORT_PARAM_TYPE structure
       
   538 		return OMX_ErrorUnsupportedIndex;
       
   539 		}
       
   540 	default:
       
   541 		{
       
   542 		TBool updateProcessingFunction = EFalse;
       
   543 		omxRetValue =
       
   544 			pPort->SetParameter(
       
   545 				aParamIndex,
       
   546 				apComponentParameterStructure,
       
   547 				updateProcessingFunction);
       
   548 
       
   549 		if (OMX_ErrorNone == omxRetValue)
       
   550 			{
       
   551 			if (updateProcessingFunction)
       
   552 				{
       
   553 				omxRetValue = iProcessingFunction.ParamIndication(
       
   554 					aParamIndex,
       
   555 					apComponentParameterStructure);
       
   556 				}
       
   557 			}
       
   558 
       
   559 		}
       
   560 		};
       
   561 
       
   562 	return omxRetValue;
       
   563 
       
   564 	}
       
   565 
       
   566 OMX_ERRORTYPE
       
   567 COmxILPortManager::GetConfig(OMX_INDEXTYPE aConfigIndex,
       
   568 							 TAny* apComponentConfigStructure) const
       
   569 	{
       
   570     DEBUG_PRINTF(_L8("COmxILPortManager::GetConfig"));
       
   571 
       
   572 	TInt index = FindConfigIndex(aConfigIndex);
       
   573 	if (KErrNotFound == index)
       
   574 		{
       
   575 		return OMX_ErrorUnsupportedIndex;
       
   576 		}
       
   577 
       
   578 	// Obtain the port index
       
   579 	OMX_U32 portIndex;
       
   580 	if (OMX_ErrorNone != GetPortIndexFromOmxStruct(apComponentConfigStructure,
       
   581 												   portIndex))
       
   582 		{
       
   583 		return OMX_ErrorBadPortIndex;
       
   584 		}
       
   585 
       
   586 	// Now delegate to the specific port
       
   587 	return iAllPorts[portIndex]->GetConfig(
       
   588 		aConfigIndex,
       
   589 		apComponentConfigStructure);
       
   590 
       
   591 	}
       
   592 
       
   593 OMX_ERRORTYPE
       
   594 COmxILPortManager::SetConfig(OMX_INDEXTYPE aConfigIndex,
       
   595 							 const TAny* apComponentConfigStructure)
       
   596 	{
       
   597     DEBUG_PRINTF(_L8("COmxILPortManager::SetConfig"));
       
   598 
       
   599 	TInt index = FindConfigIndex(aConfigIndex);
       
   600 	if (KErrNotFound == index)
       
   601 		{
       
   602 		return OMX_ErrorUnsupportedIndex;
       
   603 		}
       
   604 
       
   605 	// Obtain the port index
       
   606 	OMX_U32 portIndex;
       
   607 	if (OMX_ErrorNone != GetPortIndexFromOmxStruct(apComponentConfigStructure,
       
   608 												   portIndex))
       
   609 		{
       
   610 		return OMX_ErrorBadPortIndex;
       
   611 		}
       
   612 
       
   613 	TBool updateProcessingFunction = EFalse;
       
   614 	OMX_ERRORTYPE omxRetValue =
       
   615 		iAllPorts[portIndex]->SetConfig(
       
   616 			aConfigIndex,
       
   617 			apComponentConfigStructure,
       
   618 			updateProcessingFunction);
       
   619 
       
   620 	if (OMX_ErrorNone == omxRetValue)
       
   621 		{
       
   622 		if (updateProcessingFunction)
       
   623 			{
       
   624 			omxRetValue = iProcessingFunction.ConfigIndication(
       
   625 				aConfigIndex,
       
   626 				apComponentConfigStructure);
       
   627 			}
       
   628 		}
       
   629 
       
   630 	return omxRetValue;
       
   631 
       
   632 	}
       
   633 
       
   634 OMX_ERRORTYPE
       
   635 COmxILPortManager::GetExtensionIndex(
       
   636 	OMX_STRING aParameterName,
       
   637 	OMX_INDEXTYPE* apIndexType) const
       
   638 	{
       
   639     DEBUG_PRINTF(_L8("COmxILPortManager::GetExtensionIndex"));
       
   640 
       
   641 	// See if the extension index is supported by any of the ports...
       
   642 	const TInt portCount = iAllPorts.Count();
       
   643 	OMX_ERRORTYPE retValue = OMX_ErrorNone;
       
   644 	for (TUint i = 0; i< portCount; ++i)
       
   645 		{
       
   646 		retValue = iAllPorts[i]->GetExtensionIndex(aParameterName,
       
   647 												   apIndexType);
       
   648 		if (retValue != OMX_ErrorUnsupportedIndex)
       
   649 			{
       
   650 			return retValue;
       
   651 			}
       
   652 		}
       
   653 
       
   654 	return OMX_ErrorUnsupportedIndex;
       
   655 
       
   656 	}
       
   657 
       
   658 OMX_ERRORTYPE
       
   659 COmxILPortManager::PopulateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr,
       
   660 								  OMX_U32 aPortIndex,
       
   661 								  OMX_PTR apAppPrivate,
       
   662 								  OMX_U32 aSizeBytes,
       
   663 								  OMX_U8* apBuffer,
       
   664 								  TBool& portPopulationCompleted,
       
   665 								  OMX_BOOL aPortIsDisabled /* = OMX_FALSE */ )
       
   666 	{
       
   667     DEBUG_PRINTF(_L8("COmxILPortManager::PopulateBuffer"));
       
   668 
       
   669 	// Check the index of the port..
       
   670 	if (CheckPortIndex(aPortIndex) != OMX_ErrorNone)
       
   671 		{
       
   672 		return OMX_ErrorBadPortIndex;
       
   673 		}
       
   674 
       
   675 	// Grab the port here...
       
   676 	COmxILPort* pPort = iAllPorts[aPortIndex];
       
   677 
       
   678 	if (OMX_TRUE == aPortIsDisabled &&
       
   679 		pPort->IsEnabled() &&
       
   680 		!pPort->IsTransitioningToEnabled())
       
   681 		{
       
   682 		// There is an indication from the FSM that the port must be disabled,
       
   683 		// otherwise, the buffer allocation is not allowed in the current
       
   684 		// state. Note that a port may be transitioning to enabled and in that
       
   685 		// case the buffer population must be allowed...
       
   686 		return OMX_ErrorIncorrectStateOperation;
       
   687 		}
       
   688 
       
   689 	// Check that in case of tunnelling, this port is not buffer supplier...
       
   690 	if (pPort->IsTunnelledAndBufferSupplier())
       
   691 		{
       
   692 		return OMX_ErrorBadPortIndex;
       
   693 		}
       
   694 
       
   695 	// Now delegate to the port...
       
   696 	OMX_ERRORTYPE omxRetValue;
       
   697 	if (OMX_ErrorNone != (omxRetValue = pPort->PopulateBuffer(
       
   698 							  appBufferHdr,
       
   699 							  apAppPrivate,
       
   700 							  aSizeBytes,
       
   701 							  apBuffer,
       
   702 							  portPopulationCompleted)))
       
   703 		{
       
   704 		return omxRetValue;
       
   705 		}
       
   706 
       
   707 	if (portPopulationCompleted && pPort->IsTransitioningToEnabled())
       
   708 		{
       
   709 		// This is a case of port being enabled...  Inform the port that it
       
   710 		// has been enabled..
       
   711 		pPort->SetTransitionToEnabledCompleted();
       
   712 
       
   713 		// For each enabled port, the IL Client must be notified with an
       
   714 		// enabled completion event...
       
   715 		omxRetValue = iCallbacks.CommandCompleteNotification(
       
   716 			OMX_CommandPortEnable, pPort->Index());
       
   717 		}
       
   718 
       
   719 	return omxRetValue;
       
   720 
       
   721 	}
       
   722 
       
   723 
       
   724 OMX_ERRORTYPE
       
   725 COmxILPortManager::FreeBuffer(OMX_U32 aPortIndex,
       
   726 							  OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   727 							  TBool& portDepopulationCompleted,
       
   728 							  OMX_BOOL aPortIsDisabled /* = OMX_FALSE */)
       
   729 	{
       
   730     DEBUG_PRINTF2(_L8("COmxILPortManager::FreeBuffer : BUFFER [%X]"), apBufferHeader);
       
   731 
       
   732 	// Check the index of the port..
       
   733 	if (CheckPortIndex(aPortIndex) != OMX_ErrorNone)
       
   734 		{
       
   735 		return OMX_ErrorBadPortIndex;
       
   736 		}
       
   737 
       
   738 	// Grab the port here...
       
   739 	COmxILPort* pPort = iAllPorts[aPortIndex];
       
   740 
       
   741 	// Check that in case of tunnelling, this port is not buffer supplier...
       
   742 	if (pPort->IsTunnelledAndBufferSupplier())
       
   743 		{
       
   744 		return OMX_ErrorBadPortIndex;
       
   745 		}
       
   746 
       
   747 	TBool errorPortUnpopulated = EFalse;
       
   748 	if (OMX_TRUE == aPortIsDisabled &&
       
   749 		pPort->IsEnabled())
       
   750 		{
       
   751 		// There is an indication from the FSM that the port should be
       
   752 		// disabled. If that's not the case, the buffer deallocation will raise
       
   753 		// an OMX_ErrorPortUnpopulated error in the current state.
       
   754 
       
   755 		if (!pPort->IsBufferAtHome(apBufferHeader))
       
   756 			{
       
   757 			// FreeBuffer will normally be called in a situation where we are
       
   758 			// not suppliers and the supplier already got the buffer. So the
       
   759 			// buffer won't be on our side almost never.
       
   760 
       
   761 			if (!iTimePorts[aPortIndex] || !iImmediateReturnTimeBuffer)
       
   762 				{
       
   763 				// We'll tell the PF to remove this
       
   764 				// header from its queues, in case this is called in some strange
       
   765 				// situation (should not happen if the tunnelled component is well
       
   766 				// behaved)...
       
   767 				iProcessingFunction.BufferRemovalIndication(
       
   768 					apBufferHeader,
       
   769 					pPort->Direction());
       
   770 				}
       
   771 
       
   772 			// Set the returned flag as this buffer will not count as "away"
       
   773 			// anymore...
       
   774 			pPort->SetBufferReturned(apBufferHeader);
       
   775 			}
       
   776 
       
   777 		// We have to send the Port Unpopulated Error...
       
   778 		errorPortUnpopulated = ETrue;
       
   779 		}
       
   780 
       
   781 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   782 	// Now delegate to the port...
       
   783 	if (OMX_ErrorNone != (omxRetValue = pPort->FreeBuffer(
       
   784 							  apBufferHeader,
       
   785 							  portDepopulationCompleted)))
       
   786 		{
       
   787 		return omxRetValue;
       
   788 		}
       
   789 
       
   790 	if (errorPortUnpopulated)
       
   791 		{
       
   792 		if (OMX_ErrorNone !=
       
   793 			(omxRetValue =
       
   794 			 iCallbacks.ErrorEventNotification(OMX_ErrorPortUnpopulated)))
       
   795 			{
       
   796 			return omxRetValue;
       
   797 			}
       
   798 		}
       
   799 
       
   800 
       
   801 	if (portDepopulationCompleted)
       
   802 		{
       
   803 		if (pPort->IsTransitioningToDisabled())
       
   804 			{
       
   805 			// Here we must complete the OMX_CommandPortDisable command
       
   806 
       
   807 			// Set the state of the port to  disabled as the command has already
       
   808 			// completed...
       
   809 			pPort->SetTransitionToDisabledCompleted();
       
   810 
       
   811 			// For each disabled port, the IL Client must be notified
       
   812 			// with a disabled completion event...
       
   813 			omxRetValue = iCallbacks.CommandCompleteNotification(
       
   814 				OMX_CommandPortDisable, aPortIndex);
       
   815 
       
   816 			// Clear this flag here. Otherwise, the FSM would inform the client
       
   817 			// of a successful transition to OMX_StateIdle which is not the
       
   818 			// case...
       
   819 			portDepopulationCompleted = EFalse;
       
   820 			}
       
   821 		}
       
   822 
       
   823 	return omxRetValue;
       
   824 
       
   825 	}
       
   826 
       
   827 OMX_ERRORTYPE
       
   828 COmxILPortManager::TunnelRequest(OMX_U32 aPortIndex,
       
   829 								 OMX_HANDLETYPE aTunneledComp,
       
   830 								 OMX_U32 aTunneledPort,
       
   831 								 OMX_TUNNELSETUPTYPE* apTunnelSetup,
       
   832 								 OMX_BOOL aPortIsDisabled /* = OMX_FALSE */)
       
   833 	{
       
   834     DEBUG_PRINTF3(_L8("COmxILPortManager::TunnelRequest : aTunneledComp [%X] aTunneledPort [%d]"), aTunneledComp, aTunneledPort);
       
   835 
       
   836 	// Check the index of the port..
       
   837 	if (CheckPortIndex(aPortIndex) != OMX_ErrorNone)
       
   838 		{
       
   839 		return OMX_ErrorBadPortIndex;
       
   840 		}
       
   841 
       
   842 	// Grab the port here...
       
   843 	COmxILPort* pPort = iAllPorts[aPortIndex];
       
   844 
       
   845 	if (OMX_TRUE == aPortIsDisabled &&
       
   846 		pPort->IsEnabled())
       
   847 		{
       
   848 		// There is an indication from the FSM that the port must be disabled,
       
   849 		// otherwise, the tunnel request is not allowed in the current state.
       
   850 		return OMX_ErrorIncorrectStateOperation;
       
   851 		}
       
   852 
       
   853 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   854 	// Check whether the tunnel is being torn down...
       
   855 	if (!aTunneledComp)
       
   856 		{
       
   857 		// Tell the port...
       
   858 		if (OMX_ErrorNone !=
       
   859 			(omxRetValue = pPort->TunnelRequest(
       
   860 				aTunneledComp,
       
   861 				aTunneledPort,
       
   862 				apTunnelSetup)))
       
   863 			{
       
   864 			return omxRetValue;
       
   865 			}
       
   866 
       
   867 		if (OMX_ErrorNone !=
       
   868 			(omxRetValue = iCallbacks.DeregisterTunnelCallback(aPortIndex)))
       
   869 			{
       
   870 			// This is serious enough...
       
   871 			return OMX_ErrorInvalidComponent;
       
   872 			}
       
   873 
       
   874 		// We are done here...
       
   875 		return OMX_ErrorNone;
       
   876 		}
       
   877 
       
   878 	// Check whether the port is being re-tunnelled...
       
   879 	if (pPort->IsTunnelled())
       
   880 		{
       
   881 		// Only two valid options here:
       
   882 		// 1.- The port is completely disabled...
       
   883 		// or...
       
   884 		// 2.- The port is enabled AND component in OMX_StateLoaded
       
   885 		if ((!pPort->IsEnabled() &&
       
   886 			 !pPort->IsTransitioningToEnabled() &&
       
   887 			 !pPort->IsTransitioningToDisabled())
       
   888 			||
       
   889 			(pPort->IsEnabled() && !aPortIsDisabled))
       
   890 			{
       
   891 			if (OMX_ErrorNone !=
       
   892 				(omxRetValue = iCallbacks.DeregisterTunnelCallback(aPortIndex)))
       
   893 				{
       
   894 				return OMX_ErrorInvalidComponent;
       
   895 				}
       
   896 			}
       
   897 		else
       
   898 			{
       
   899 			return OMX_ErrorIncorrectStateOperation;
       
   900 			}
       
   901 		}
       
   902 
       
   903 	// Delegate to the port...
       
   904 	if (OMX_ErrorNone !=
       
   905 		(omxRetValue = pPort->TunnelRequest(
       
   906 			aTunneledComp,
       
   907 			aTunneledPort,
       
   908 			apTunnelSetup)))
       
   909 		{
       
   910 		return omxRetValue;
       
   911 		}
       
   912 
       
   913 	// From this point on, the port will assume that a tunnel has been
       
   914 	// successfully created. If there is a problem at other end, the IL Client
       
   915 	// will clear the tunnel on this side using ComponentTunnelRequest with
       
   916 	// NULL handle parameter
       
   917 
       
   918 	// Register the existence of a tunnel within the callback manager...
       
   919 	if (OMX_ErrorNone !=
       
   920 		(omxRetValue = iCallbacks.RegisterTunnelCallback(aPortIndex,
       
   921 													  pPort->Direction(),
       
   922 													  aTunneledComp,
       
   923 													  aTunneledPort)))
       
   924 		{
       
   925 		// This is serious enough...
       
   926 		return OMX_ErrorInvalidComponent;
       
   927 		}
       
   928 
       
   929 	return OMX_ErrorNone;
       
   930 
       
   931 	}
       
   932 
       
   933 
       
   934 OMX_ERRORTYPE
       
   935 COmxILPortManager::TunnellingBufferAllocation(TBool& aComponentPopulationCompleted,
       
   936 											  TUint32 aPortIndex /* = OMX_ALL */)
       
   937 	{
       
   938     DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferAllocation"));
       
   939 
       
   940 	aComponentPopulationCompleted = EFalse;
       
   941 
       
   942 	// Check the index of the port..
       
   943 	if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone))
       
   944 		{
       
   945 		return OMX_ErrorBadPortIndex;
       
   946 		}
       
   947 
       
   948 	const TInt portCount = iAllPorts.Count();
       
   949 	COmxILPort* pPort = 0;
       
   950 	OMX_U32 portIndex = 0;
       
   951 	TInt i=0;
       
   952 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   953 	do
       
   954 		{
       
   955 		if (aPortIndex != OMX_ALL)
       
   956 			{
       
   957 			// Grab the port here...
       
   958 			pPort = iAllPorts[aPortIndex];
       
   959 			portIndex = aPortIndex;
       
   960 			}
       
   961 		else
       
   962 			{
       
   963 			pPort = iAllPorts[i];
       
   964 			portIndex = pPort->Index();
       
   965 			}
       
   966 
       
   967 
       
   968 		if (pPort->IsEnabled() &&
       
   969 			pPort->IsTunnelledAndBufferSupplier() &&
       
   970 			!pPort->IsPopulated())
       
   971 			{
       
   972 			TBool portPopulationCompleted = EFalse;
       
   973 			if (OMX_ErrorNone !=
       
   974 				(omxRetValue = pPort->PopulateTunnel(portPopulationCompleted)))
       
   975 				{
       
   976 				// TODO: Check case of ports being enabled (error callback needed...)
       
   977 				return omxRetValue;
       
   978 				}
       
   979 
       
   980 			if (portPopulationCompleted && pPort->IsTransitioningToEnabled())
       
   981 				{
       
   982 				// This is a case of port being enabled...  Inform the port that it
       
   983 				// has been enabled..
       
   984 				pPort->SetTransitionToEnabledCompleted();
       
   985 
       
   986 				// For each enabled port, the IL Client must be notified with an
       
   987 				// enabled completion event...
       
   988 				if (OMX_ErrorNone != (
       
   989 						omxRetValue = iCallbacks.CommandCompleteNotification(
       
   990 							OMX_CommandPortEnable, portIndex)))
       
   991 					{
       
   992 					return omxRetValue;
       
   993 					}
       
   994 				}
       
   995 
       
   996 			}
       
   997 
       
   998 		// Increment loop counter
       
   999 		++i;
       
  1000 		}
       
  1001 	while (OMX_ALL == aPortIndex && i < portCount);
       
  1002 
       
  1003 	if (AllPortsPopulated())
       
  1004 		{
       
  1005 		DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferAllocation : AllPortsPopulated : [TRUE]"));
       
  1006 		aComponentPopulationCompleted = ETrue;
       
  1007 		}
       
  1008 
       
  1009 	return OMX_ErrorNone;
       
  1010 
       
  1011 	}
       
  1012 
       
  1013 OMX_ERRORTYPE
       
  1014 COmxILPortManager::TunnellingBufferDeallocation(
       
  1015 	TBool& aComponentDepopulationCompleted)
       
  1016 	{
       
  1017     DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferDeallocation"));
       
  1018 
       
  1019 	aComponentDepopulationCompleted = EFalse;
       
  1020 
       
  1021 	const TInt portCount = iAllPorts.Count();
       
  1022 	COmxILPort* pPort = 0;
       
  1023 	TInt portDepopulationCounter = 0;
       
  1024 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1025 	TBool portDepopulationCompleted = EFalse;
       
  1026 	for (TInt i=0; i<portCount; ++i)
       
  1027 		{
       
  1028 		pPort = iAllPorts[i];
       
  1029 		if (pPort->IsEnabled() && pPort->IsTunnelledAndBufferSupplier())
       
  1030 			{
       
  1031 			// TODO: Check that at this point, the ProcessingFunction must not
       
  1032 			// hold any buffer header...
       
  1033 			portDepopulationCompleted = EFalse;
       
  1034 			if (OMX_ErrorNone !=
       
  1035 				(omxRetValue = pPort->FreeTunnel(portDepopulationCompleted)))
       
  1036 				{
       
  1037 				return omxRetValue;
       
  1038 				}
       
  1039 
       
  1040 			if (pPort->IsDePopulated())
       
  1041 				{
       
  1042 				portDepopulationCounter++;
       
  1043 				}
       
  1044 			}
       
  1045 		}
       
  1046 
       
  1047 	if (AllPortsDePopulated())
       
  1048 		{
       
  1049 		DEBUG_PRINTF(_L8("COmxILPortManager::TunnellingBufferDeallocation : AllPortsDepopulated : [TRUE]"));
       
  1050 		aComponentDepopulationCompleted = ETrue;
       
  1051 		}
       
  1052 
       
  1053 	return OMX_ErrorNone;
       
  1054 
       
  1055 	}
       
  1056 
       
  1057 OMX_ERRORTYPE
       
  1058 COmxILPortManager::InitiateTunnellingDataFlow(OMX_U32 aPortIndex /* = OMX_ALL */)
       
  1059 	{
       
  1060     DEBUG_PRINTF2(_L8("COmxILPortManager::InitiateTunnellingDataFlow : PORT[%d]"), aPortIndex);
       
  1061 
       
  1062 	// Check the index of the port..
       
  1063 	if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone))
       
  1064 		{
       
  1065 		return OMX_ErrorBadPortIndex;
       
  1066 		}
       
  1067 
       
  1068 	// This is an indication that the component is ready to start exchanging
       
  1069 	// buffers... Supplier tunnelled ports must initiate the buffer exchange in
       
  1070 	// the tunnel...
       
  1071 	const TInt portCount = iAllPorts.Count();
       
  1072 	COmxILPort* pPort = 0;
       
  1073 	OMX_U32 portIndex = 0;
       
  1074 	TInt i=0;
       
  1075 	do
       
  1076 		{
       
  1077 		if (aPortIndex != OMX_ALL)
       
  1078 			{
       
  1079 			// Grab the port here...
       
  1080 			pPort = iAllPorts[aPortIndex];
       
  1081 			portIndex = aPortIndex;
       
  1082 			}
       
  1083 		else
       
  1084 			{
       
  1085 			pPort = iAllPorts[i];
       
  1086 			portIndex = pPort->Index();
       
  1087 			}
       
  1088 
       
  1089 		if (pPort->IsEnabled() && pPort->IsTunnelledAndBufferSupplier())
       
  1090 			{
       
  1091 			const TInt headerCount = pPort->Count();
       
  1092 			OMX_BUFFERHEADERTYPE* pHeader = 0;
       
  1093 			OMX_DIRTYPE portDir = OMX_DirMax;
       
  1094 			OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1095 			for (TInt j=0; j<headerCount; ++j)
       
  1096 				{
       
  1097 				// Here, there are two options:
       
  1098 				//
       
  1099 				// 1. -The port is an input port, in which case, the buffer is
       
  1100 				// directly sent to the callback manager which in turn sends it
       
  1101 				// to the tunnelled component in charge of filling it
       
  1102 				// (OMX_FillThisBuffer)
       
  1103 				//
       
  1104 				// 2.- The port is an output port, and the buffer must be sent
       
  1105 				// to the processing function to be filled before the buffer
       
  1106 				// can be sent to the tunnelled component. After that, the proc
       
  1107 				// function will send the buffer to the call back manager to be
       
  1108 				// sent to the tunnelled component (OMX_EmptyThisBuffer)...
       
  1109 				pHeader = (*pPort)[j];
       
  1110 
       
  1111 				// Check that we actually have the buffer in our side...
       
  1112 				if (!pPort->IsBufferAtHome(pHeader))
       
  1113 					{
       
  1114 					DEBUG_PRINTF2(_L8("COmxILPortManager::InitiateTunnellingDataFlow : BUFFER HEADER[%X] is not at home"),
       
  1115 								  pHeader);
       
  1116 					continue;
       
  1117 					}
       
  1118 
       
  1119 				portDir = pPort->Direction();
       
  1120 				__ASSERT_DEBUG((OMX_DirInput == portDir ||
       
  1121 								OMX_DirOutput == portDir),
       
  1122 							   User::Panic(KOmxILPortManagerPanicCategory, 1));
       
  1123 
       
  1124 				if (OMX_DirInput == portDir)
       
  1125 					{
       
  1126 					// Input port -> Send buffer to callback manager...
       
  1127 					omxRetValue =
       
  1128 						iCallbacks.BufferDoneNotification(pHeader,
       
  1129 														  portIndex,
       
  1130 														  portDir);
       
  1131 					}
       
  1132 				else
       
  1133 					{
       
  1134 					// Output port -> Send buffer to processing function...
       
  1135 					omxRetValue =
       
  1136 						iProcessingFunction.BufferIndication(pHeader,
       
  1137 															 portDir);
       
  1138 					}
       
  1139 
       
  1140 				if (omxRetValue != OMX_ErrorNone)
       
  1141 					{
       
  1142 					return omxRetValue;
       
  1143 					}
       
  1144 
       
  1145 				// Inform the port that one of its buffers has been sent
       
  1146 				// away...
       
  1147 				TBool bufferMarkedWithOwnMark = EFalse;
       
  1148 				if (!pPort->SetBufferSent(pHeader, bufferMarkedWithOwnMark))
       
  1149 					{
       
  1150 					// The buffer header was not found...
       
  1151 					return OMX_ErrorBadParameter;
       
  1152 					}
       
  1153 
       
  1154 				// For each MarkBuffer command processed, the IL Client must be notified
       
  1155 				// with an OMX_EventCommandComplete event...
       
  1156 				if (bufferMarkedWithOwnMark)
       
  1157 					{
       
  1158 					if (OMX_ErrorNone !=
       
  1159 						(omxRetValue = iCallbacks.CommandCompleteNotification(
       
  1160 							OMX_CommandMarkBuffer, portIndex)))
       
  1161 						{
       
  1162 						return omxRetValue;
       
  1163 						}
       
  1164 					}
       
  1165 
       
  1166 				} // for (TInt j=0; j<headerCount; j++)
       
  1167 			} // if (pPort->IsEnabled() && pPort->IsTunnelledAndBufferSupplier())
       
  1168 
       
  1169 		// Increment loop counter
       
  1170 		++i;
       
  1171 		}
       
  1172 	while(OMX_ALL == aPortIndex && i < portCount);
       
  1173 
       
  1174 	return OMX_ErrorNone;
       
  1175 
       
  1176 	}
       
  1177 
       
  1178 OMX_ERRORTYPE
       
  1179 COmxILPortManager::BufferIndication(
       
  1180 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
  1181 	OMX_DIRTYPE aDirection,
       
  1182 	OMX_BOOL aPortIsDisabled /* = OMX_FALSE */)
       
  1183 	{
       
  1184     DEBUG_PRINTF2(_L8("COmxILPortManager::BufferIndication : BUFFER [%X]"), apBufferHeader);
       
  1185 
       
  1186 	OMX_U32 portIndex = aDirection == OMX_DirInput ?
       
  1187 		apBufferHeader->nInputPortIndex : apBufferHeader->nOutputPortIndex;
       
  1188 
       
  1189 	// Check the index of the port..
       
  1190 	if (CheckPortIndex(portIndex) != OMX_ErrorNone)
       
  1191 		{
       
  1192 		return OMX_ErrorBadPortIndex;
       
  1193 		}
       
  1194 
       
  1195 	// Grab the port here...
       
  1196 	COmxILPort* pPort = iAllPorts[portIndex];
       
  1197 
       
  1198 	// Check that port direction is the correct one...
       
  1199 	if (pPort->Direction() != aDirection)
       
  1200 		{
       
  1201 		return OMX_ErrorBadPortIndex;
       
  1202 		}
       
  1203 
       
  1204 	if (!pPort->IsEnabled() &&
       
  1205 		!pPort->IsTransitioningToDisabled() &&
       
  1206 		!pPort->IsTransitioningToEnabled())
       
  1207 		{
       
  1208 		return OMX_ErrorIncorrectStateOperation;
       
  1209 		}
       
  1210 
       
  1211 	// Check port enabled property...
       
  1212 	if (OMX_TRUE == aPortIsDisabled &&
       
  1213 		pPort->IsEnabled())
       
  1214 		{
       
  1215 		// There is an indication from the FSM that the port must be disabled,
       
  1216 		// otherwise, the buffer indication is not allowed in the current
       
  1217 		// state.
       
  1218 		return OMX_ErrorIncorrectStateOperation;
       
  1219 		}
       
  1220 
       
  1221 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1222 	// Check whether this port is a buffer supplier...
       
  1223 	if (pPort->IsTunnelledAndBufferSupplier() &&
       
  1224 		pPort->IsTransitioningToDisabled())
       
  1225 		{
       
  1226 		// Set the state of the port to disabled as the command has already
       
  1227 		// completed...
       
  1228 		if (!pPort->SetBufferReturned(apBufferHeader))
       
  1229 			{
       
  1230 			// The buffer header was not found...
       
  1231 			return OMX_ErrorBadParameter;
       
  1232 			}
       
  1233 
       
  1234 		if (pPort->HasAllBuffersAtHome())
       
  1235 			{
       
  1236 			// All buffers at home.. we can initiate here the
       
  1237 			// depopulation of the tunnel...
       
  1238 			TBool portDepopulationCompleted = EFalse;
       
  1239 			if (OMX_ErrorNone !=
       
  1240 				(omxRetValue = pPort->FreeTunnel(portDepopulationCompleted)))
       
  1241 				{
       
  1242 				return omxRetValue;
       
  1243 				}
       
  1244 
       
  1245 			// Inform the port that the disabled command has
       
  1246 			// completed...
       
  1247 			pPort->SetTransitionToDisabledCompleted();
       
  1248 
       
  1249 			// For each disabled port, the IL Client must be notified
       
  1250 			// with a port disabled completion event...
       
  1251 			if (OMX_ErrorNone !=
       
  1252 				(omxRetValue = iCallbacks.CommandCompleteNotification(
       
  1253 					OMX_CommandPortDisable, portIndex)))
       
  1254 				{
       
  1255 				return omxRetValue;
       
  1256 				}
       
  1257 			}
       
  1258 
       
  1259 		// Make sure the buffer contents are cleared...
       
  1260 		TOmxILUtil::ClearBufferContents(apBufferHeader);
       
  1261 
       
  1262 		// ... we are done.. no need to send the buffer to the
       
  1263 		// processing function...
       
  1264 		return OMX_ErrorNone;
       
  1265 
       
  1266 		} // if (pPort->IsTransitioningToDisabled())
       
  1267 
       
  1268 
       
  1269 	// Inform the port that one of its buffers is going to be sent to the
       
  1270 	// processing function (exception applies to OMX_PortDomainOther ports) ... 
       
  1271 	// The port will also mark this buffer if the port
       
  1272 	// has pending marks to be signalled... The buffer marks are finally
       
  1273 	// processed/propagated by the callback manager once the buffer has been
       
  1274 	// consumed by the processing function...
       
  1275 	TBool bufferMarkedWithOwnMark = EFalse;
       
  1276 	if (!pPort->SetBufferSent(apBufferHeader, bufferMarkedWithOwnMark))
       
  1277 		{
       
  1278 		return OMX_ErrorBadParameter;
       
  1279 		}
       
  1280 
       
  1281 	// For each MarkBuffer command processed, the IL Client must be notified
       
  1282 	// with an OMX_EventCommandComplete event...
       
  1283 	if (bufferMarkedWithOwnMark)
       
  1284 		{
       
  1285 		if (OMX_ErrorNone !=
       
  1286 			(omxRetValue = iCallbacks.CommandCompleteNotification(
       
  1287 				OMX_CommandMarkBuffer, portIndex)))
       
  1288 			{
       
  1289 			return omxRetValue;
       
  1290 			}
       
  1291 		}
       
  1292 
       
  1293 	if (iImmediateReturnTimeBuffer && iTimePorts[portIndex])
       
  1294 		{
       
  1295 		// OMX_OTHER_FormatTime ports (such as COmxILClientClockPort) needs
       
  1296 		// to return the buffer sooner to the buffer supplier component
       
  1297 		OMX_TIME_MEDIATIMETYPE* pMediaTime =
       
  1298 			reinterpret_cast<OMX_TIME_MEDIATIMETYPE*>(apBufferHeader->pBuffer);
       
  1299 
       
  1300 		OMX_TIME_MEDIATIMETYPE timeInfo;
       
  1301 		if (pMediaTime)
       
  1302 			{
       
  1303 			timeInfo = *pMediaTime;
       
  1304 			}
       
  1305 
       
  1306 		// Return the buffer (send the Buffer Done notification) via callback now.
       
  1307 		apBufferHeader->nFilledLen = 0;
       
  1308 
       
  1309 		OMX_ERRORTYPE err = iCallbacks.ClockBufferDoneNotification(
       
  1310 			apBufferHeader, portIndex, aDirection);
       
  1311 
       
  1312 		if (err != OMX_ErrorNone)
       
  1313 			{
       
  1314 			return err;
       
  1315 			}
       
  1316 
       
  1317 		if (pMediaTime)
       
  1318 			{
       
  1319 			// Send time update to the processing function
       
  1320 			err = iProcessingFunction.MediaTimeIndication(timeInfo);
       
  1321 			}
       
  1322 
       
  1323 		__ASSERT_DEBUG(err != OMX_ErrorNotImplemented,
       
  1324 					   User::Panic(KOmxILPortManagerPanicCategory, 1));
       
  1325 
       
  1326 		return err;
       
  1327 		}
       
  1328 	
       
  1329 	return iProcessingFunction.BufferIndication(apBufferHeader,
       
  1330 												aDirection);
       
  1331 	}
       
  1332 
       
  1333 
       
  1334 OMX_ERRORTYPE
       
  1335 COmxILPortManager::BufferReturnIndication(
       
  1336 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
  1337 	OMX_DIRTYPE aDirection,
       
  1338 	TBool& aAllBuffersReturned)
       
  1339 	{
       
  1340     DEBUG_PRINTF2(_L8("COmxILPortManager::BufferReturnIndication : [%X]"), apBufferHeader);
       
  1341 
       
  1342 	aAllBuffersReturned = EFalse;
       
  1343 
       
  1344 	OMX_U32 portIndex = aDirection == OMX_DirInput ?
       
  1345 		apBufferHeader->nInputPortIndex : apBufferHeader->nOutputPortIndex;
       
  1346 
       
  1347 	// Check the index of the port..
       
  1348 	if (CheckPortIndex(portIndex) != OMX_ErrorNone)
       
  1349 		{
       
  1350 		return OMX_ErrorBadPortIndex;
       
  1351 		}
       
  1352 
       
  1353 	// Grab the port here...
       
  1354 	COmxILPort* pPort = iAllPorts[portIndex];
       
  1355 
       
  1356 	// Check that port direction is the correct one...
       
  1357 	if (pPort->Direction() != aDirection)
       
  1358 		{
       
  1359 		return OMX_ErrorBadPortIndex;
       
  1360 		}
       
  1361 
       
  1362 
       
  1363 	if (!pPort->IsEnabled())
       
  1364 		{
       
  1365 		return OMX_ErrorBadPortIndex;
       
  1366 		}
       
  1367 
       
  1368 	// Check that this port must be buffer supplier...
       
  1369 	if (!pPort->IsTunnelledAndBufferSupplier())
       
  1370 		{
       
  1371 		return OMX_ErrorBadPortIndex;
       
  1372 		}
       
  1373 
       
  1374 	// Inform the port that a buffer has returned...
       
  1375 	if (!pPort->SetBufferReturned(apBufferHeader))
       
  1376 		{
       
  1377 		// The buffer header was not found...
       
  1378 		return OMX_ErrorBadParameter;
       
  1379 		}
       
  1380 
       
  1381 	// Make sure the buffer contents are cleared...
       
  1382 	TOmxILUtil::ClearBufferContents(apBufferHeader);
       
  1383 
       
  1384 	if (pPort->HasAllBuffersAtHome())
       
  1385 		{
       
  1386 		aAllBuffersReturned = ETrue;
       
  1387 		}
       
  1388 
       
  1389 	return OMX_ErrorNone;
       
  1390 
       
  1391 	}
       
  1392 
       
  1393 OMX_ERRORTYPE
       
  1394 COmxILPortManager::BufferFlushIndicationFlushCommand(
       
  1395 	TUint32 aPortIndex, TBool aEjectBuffers /* = ETrue */)
       
  1396 	{
       
  1397     DEBUG_PRINTF2(_L8("COmxILPortManager::BufferFlushIndicationFlushCommand PORT[%d]"), aPortIndex);
       
  1398 
       
  1399 	// Check the index of the port..
       
  1400 	if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone))
       
  1401 		{
       
  1402 		return OMX_ErrorBadPortIndex;
       
  1403 		}
       
  1404 
       
  1405 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1406 	RPointerArray<COmxILPort> portsToFlush;
       
  1407 	RPointerArray<COmxILPort> portsToNotify;
       
  1408 	const TInt portCount = iAllPorts.Count();
       
  1409 	COmxILPort* pPort = 0;
       
  1410 	TInt i=0;
       
  1411 	TBool flushSuccessful;
       
  1412 	do
       
  1413 		{
       
  1414 		flushSuccessful = ETrue;
       
  1415 		if (aPortIndex != OMX_ALL)
       
  1416 			{
       
  1417 			// Grab the port here...
       
  1418 			pPort = iAllPorts[aPortIndex];
       
  1419 			}
       
  1420 		else
       
  1421 			{
       
  1422 			pPort = iAllPorts[i];
       
  1423 			}
       
  1424 
       
  1425 		if (pPort->IsEnabled() && pPort->Count())
       
  1426 			{
       
  1427 			if (pPort->IsTunnelledAndBufferSupplier() &&
       
  1428 				!pPort->HasAllBuffersAtHome())
       
  1429 				{
       
  1430 				// Remove buffers from PF only...
       
  1431 				RemoveBuffersFromPfOrCm(pPort, OMX_TRUE);
       
  1432 
       
  1433 				if (aEjectBuffers)
       
  1434 					{
       
  1435 					// Now we need to send input buffers upstream and ouput
       
  1436 					// buffers to the PF...
       
  1437 					if ((omxRetValue = InitiateTunnellingDataFlow())
       
  1438 						!= OMX_ErrorNone)
       
  1439 						{
       
  1440 						// The flush has failed, we need to notify the IL Cient
       
  1441 						// via EventHandler...
       
  1442 						iCallbacks.ErrorEventNotification(omxRetValue);
       
  1443 						flushSuccessful = EFalse;
       
  1444 						}
       
  1445 					}
       
  1446 
       
  1447 				}
       
  1448 			else
       
  1449 				{
       
  1450 				portsToFlush.Append(pPort);
       
  1451 				}
       
  1452 			}
       
  1453 		// Notify flushing completed, even if there was nothing to
       
  1454 		// flush...
       
  1455 		if (flushSuccessful)
       
  1456 			{
       
  1457 			portsToNotify.Append(pPort);
       
  1458 			}
       
  1459 
       
  1460 		// Increment loop counter
       
  1461 		++i;
       
  1462 		}
       
  1463 	while(OMX_ALL == aPortIndex && i < portCount);
       
  1464 
       
  1465 	const TInt flushCount = portsToFlush.Count();
       
  1466 	const TInt notifyCount = portsToNotify.Count();
       
  1467 
       
  1468 
       
  1469 	if (iAllPorts.Count() == flushCount)
       
  1470 		{
       
  1471 		omxRetValue = iProcessingFunction.BufferFlushingIndication(
       
  1472 			OMX_ALL,
       
  1473 			OMX_DirMax);
       
  1474 		}
       
  1475 	else
       
  1476 		{
       
  1477 		for (i=0; i<flushCount && OMX_ErrorNone == omxRetValue; ++i)
       
  1478 			{
       
  1479 			pPort = portsToFlush[i];
       
  1480 			omxRetValue = iProcessingFunction.BufferFlushingIndication(
       
  1481 				pPort->Index(),
       
  1482 				pPort->Direction());
       
  1483 			}
       
  1484 		}
       
  1485 
       
  1486 	for (i=0; i<notifyCount && OMX_ErrorNone == omxRetValue; ++i)
       
  1487 		{
       
  1488 		pPort = portsToNotify[i];
       
  1489 		omxRetValue = iCallbacks.CommandCompleteNotification(OMX_CommandFlush,
       
  1490 											   portsToNotify[i]->Index());
       
  1491 		}
       
  1492 
       
  1493 	portsToFlush.Close();
       
  1494 	portsToNotify.Close();
       
  1495 
       
  1496 	return omxRetValue;
       
  1497 
       
  1498 	}
       
  1499 
       
  1500 OMX_ERRORTYPE
       
  1501 COmxILPortManager::BufferFlushIndicationPauseOrExeToIdleCommand(
       
  1502 	TBool& aAllBuffersReturnedToSuppliers)
       
  1503 	{
       
  1504     DEBUG_PRINTF(_L8("COmxILPortManager::BufferFlushIndicationPauseOrExeToIdleCommand"));
       
  1505 
       
  1506 	aAllBuffersReturnedToSuppliers = EFalse;
       
  1507 
       
  1508 	const TInt portCount = iAllPorts.Count();
       
  1509 	TBool foundBufferSupplierThatNeedsToWait = EFalse;
       
  1510 	COmxILPort* pPort = 0;
       
  1511 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1512 	for (TInt i=0; i<portCount; ++i)
       
  1513 		{
       
  1514 		pPort = iAllPorts[i];
       
  1515 
       
  1516 		if (pPort->IsEnabled() && pPort->Count())
       
  1517 			{
       
  1518 			if (pPort->IsTunnelledAndBufferSupplier() &&
       
  1519 				!pPort->HasAllBuffersAtHome())
       
  1520 				{
       
  1521 				if (!RemoveBuffersFromPfOrCm(pPort))
       
  1522 					{
       
  1523 					// This port will have to wait to get some of its buffers
       
  1524 					// returned by the tunnelled port...
       
  1525 					foundBufferSupplierThatNeedsToWait = ETrue;
       
  1526 					}
       
  1527 				continue;
       
  1528 				}
       
  1529 
       
  1530 			if (OMX_ErrorNone !=
       
  1531 				(omxRetValue = iProcessingFunction.BufferFlushingIndication(
       
  1532 					pPort->Index(),
       
  1533 					pPort->Direction())))
       
  1534 				{
       
  1535 				return omxRetValue;
       
  1536 				}
       
  1537 			}
       
  1538 		}
       
  1539 
       
  1540 	if (!foundBufferSupplierThatNeedsToWait)
       
  1541 		{
       
  1542 		aAllBuffersReturnedToSuppliers = ETrue;
       
  1543 		}
       
  1544 
       
  1545 	return OMX_ErrorNone;
       
  1546 
       
  1547 	}
       
  1548 
       
  1549 OMX_ERRORTYPE
       
  1550 COmxILPortManager::PortEnableIndication(
       
  1551 	TUint32 aPortIndex,
       
  1552 	TBool aIndicationIsFinal)
       
  1553 	{
       
  1554     DEBUG_PRINTF3(_L8("COmxILPortManager::PortEnableIndication: PORT[%d] TRANSITIONISFINAL[%d]"), aPortIndex, aIndicationIsFinal);
       
  1555 
       
  1556 	// Check the index of the port..
       
  1557 	if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone))
       
  1558 		{
       
  1559 		return OMX_ErrorBadPortIndex;
       
  1560 		}
       
  1561 
       
  1562 	const TInt portCount = iAllPorts.Count();
       
  1563 	COmxILPort* pPort = 0;
       
  1564 	OMX_U32 portIndex = 0;
       
  1565 	TInt i=0;
       
  1566 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1567 	do
       
  1568 		{
       
  1569 		// We do this so we loop or not depending on the needs...
       
  1570 		if (aPortIndex != OMX_ALL)
       
  1571 			{
       
  1572 			// Grab the port here...
       
  1573 			pPort = iAllPorts[aPortIndex];
       
  1574 			portIndex = aPortIndex;
       
  1575 			}
       
  1576 		else
       
  1577 			{
       
  1578 			pPort = iAllPorts[i];
       
  1579 			portIndex = pPort->Index();
       
  1580 			}
       
  1581 
       
  1582 		// If port is already enabled, just indicate that the enable command has
       
  1583 		// completed successfully
       
  1584 		if (pPort->IsEnabled())
       
  1585 			{
       
  1586 			if (OMX_ErrorNone !=
       
  1587 				(omxRetValue =
       
  1588 				 iCallbacks.CommandCompleteNotification(
       
  1589 					 OMX_CommandPortEnable, portIndex)))
       
  1590 				{
       
  1591 				return omxRetValue;
       
  1592 				}
       
  1593 
       
  1594 			++i;
       
  1595 			continue;
       
  1596 			}
       
  1597 
       
  1598 		// First check that no-one port is currently transitioning to
       
  1599 		// Enabled...
       
  1600 		if (pPort->IsTransitioningToEnabled() ||
       
  1601 			pPort->IsTransitioningToDisabled())
       
  1602 			{
       
  1603 			// Send an error event...  The spec mandates that the nData2 and
       
  1604 			// the pEventData are 0 and NULL respectively, but they could be
       
  1605 			// used here to hand some information like the index of the port
       
  1606 			// that has failed...
       
  1607 			if (OMX_ErrorNone !=
       
  1608 				(omxRetValue =
       
  1609 				 iCallbacks.ErrorEventNotification(OMX_ErrorPortUnresponsiveDuringAllocation)))
       
  1610 				{
       
  1611 				return omxRetValue;
       
  1612 				}
       
  1613 
       
  1614 			if (OMX_ALL == aPortIndex)
       
  1615 				{
       
  1616 				++i;
       
  1617 				continue;
       
  1618 				}
       
  1619 			else
       
  1620 				{
       
  1621 				return OMX_ErrorUndefined;
       
  1622 				}
       
  1623 			}
       
  1624 
       
  1625 		if (aIndicationIsFinal)
       
  1626 			{
       
  1627 			// Inform the port that it has been enabled..
       
  1628 			pPort->SetTransitionToEnabledCompleted();
       
  1629 
       
  1630 			// For each enabled port, the IL Client must be notified
       
  1631 			// with an enabled completion event...
       
  1632 			if (OMX_ErrorNone !=
       
  1633 				(omxRetValue =
       
  1634 				 iCallbacks.CommandCompleteNotification(
       
  1635 					 OMX_CommandPortEnable, portIndex)))
       
  1636 				{
       
  1637 				return omxRetValue;
       
  1638 				}
       
  1639 
       
  1640 			}
       
  1641 		else
       
  1642 			{
       
  1643 			// Inform the port that it is being enabled..
       
  1644 			pPort->SetTransitionToEnabled();
       
  1645 			}
       
  1646 
       
  1647 		// Increment loop counter
       
  1648 		++i;
       
  1649 		}
       
  1650 	while(OMX_ALL == aPortIndex && i < portCount);
       
  1651 
       
  1652 	return OMX_ErrorNone;
       
  1653 
       
  1654 	}
       
  1655 
       
  1656 OMX_ERRORTYPE
       
  1657 COmxILPortManager::PortDisableIndication(
       
  1658 	TUint32 aPortIndex)
       
  1659 	{
       
  1660     DEBUG_PRINTF2(_L8("COmxILPortManager::PortDisableIndication: PORT[%d] "), aPortIndex);
       
  1661 
       
  1662 	// Check the index of the port..
       
  1663 	if ((OMX_ALL != aPortIndex) && (CheckPortIndex(aPortIndex) != OMX_ErrorNone))
       
  1664 		{
       
  1665 		return OMX_ErrorBadPortIndex;
       
  1666 		}
       
  1667 
       
  1668 	const TInt portCount = iAllPorts.Count();
       
  1669 	COmxILPort* pPort = 0;
       
  1670 	OMX_U32 portIndex = 0;
       
  1671 	TInt i=0;
       
  1672 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1673 	do
       
  1674 		{
       
  1675 		if (aPortIndex != OMX_ALL)
       
  1676 			{
       
  1677 			// Grab the port here...
       
  1678 			pPort = iAllPorts[aPortIndex];
       
  1679 			portIndex = aPortIndex;
       
  1680 			}
       
  1681 		else
       
  1682 			{
       
  1683 			pPort = iAllPorts[i];
       
  1684 			portIndex = pPort->Index();
       
  1685 			}
       
  1686 
       
  1687 		// If port is already disabled, just indicate that the disable command has
       
  1688 		// completed successfully
       
  1689 		if (!pPort->IsEnabled())
       
  1690 			{
       
  1691 			if (OMX_ErrorNone !=
       
  1692 				(omxRetValue =
       
  1693 				 iCallbacks.CommandCompleteNotification(
       
  1694 					 OMX_CommandPortDisable, portIndex)))
       
  1695 				{
       
  1696 				return omxRetValue;
       
  1697 				}
       
  1698 
       
  1699 			++i;
       
  1700 			continue;
       
  1701 			}
       
  1702 
       
  1703 		// First check that no-one port is currently transitioning to
       
  1704 		// Disabled...
       
  1705 		if (pPort->IsTransitioningToDisabled() ||
       
  1706 			pPort->IsTransitioningToEnabled())
       
  1707 			{
       
  1708 			// Send an error event...  The spec mandates that the nData2 and
       
  1709 			// the pEventData are 0 and NULL respectively, but they could be
       
  1710 			// used here to hand some information like the index of the port
       
  1711 			// that has failed...
       
  1712 			if (OMX_ErrorNone !=
       
  1713 				(omxRetValue =
       
  1714 				 iCallbacks.ErrorEventNotification(OMX_ErrorPortUnresponsiveDuringAllocation)))
       
  1715 				{
       
  1716 				return omxRetValue;
       
  1717 				}
       
  1718 
       
  1719 			if (OMX_ALL == aPortIndex)
       
  1720 				{
       
  1721 				++i;
       
  1722 				continue;
       
  1723 				}
       
  1724 			else
       
  1725 				{
       
  1726 				return OMX_ErrorUndefined;
       
  1727 				}
       
  1728 
       
  1729 			}
       
  1730 
       
  1731 		if (pPort->IsTunnelledAndBufferSupplier())
       
  1732 			{
       
  1733 			if (!pPort->HasAllBuffersAtHome() && !RemoveBuffersFromPfOrCm(pPort))
       
  1734 				{
       
  1735 				// Inform the port that it is being disabled
       
  1736 				pPort->SetTransitionToDisabled();
       
  1737 				// This port will have to wait to get all its buffers
       
  1738 				// returned by the tunnelled port...
       
  1739 				}
       
  1740 			else
       
  1741 				{
       
  1742 				// Buffer supplier with all buffers at home.. we can
       
  1743 				// initiate here the depopulation of the tunnel...
       
  1744 
       
  1745 				// This boolean is not used here ...
       
  1746 				TBool portDepopulationCompleted = EFalse;
       
  1747 
       
  1748 				// Better to ignore here any possible error in
       
  1749 				// FreeTunnel... nothing we can do about it...
       
  1750 				if (OMX_ErrorNone !=
       
  1751 					(omxRetValue =
       
  1752 					 pPort->FreeTunnel(portDepopulationCompleted)))
       
  1753 					{
       
  1754 					return omxRetValue;
       
  1755 					}
       
  1756 
       
  1757 				// Inform the port that the disabled command has
       
  1758 				// completed...
       
  1759 				pPort->SetTransitionToDisabledCompleted();
       
  1760 
       
  1761 				// For each disabled port, the IL Client must be notified
       
  1762 				// with a disabled completion event...
       
  1763 				if (OMX_ErrorNone !=
       
  1764 					(omxRetValue =
       
  1765 					 iCallbacks.CommandCompleteNotification(
       
  1766 						 OMX_CommandPortDisable, portIndex)))
       
  1767 					{
       
  1768 					return omxRetValue;
       
  1769 					}
       
  1770 
       
  1771 				} // else <- if (!pPort->HasAllBuffersAtHome())
       
  1772 
       
  1773 			} // if (pPort->IsTunnelledAndBufferSupplier())
       
  1774 		else
       
  1775 			{
       
  1776 			if (pPort->Count() > 0)
       
  1777 				{
       
  1778 				if (OMX_ErrorNone !=
       
  1779 					(omxRetValue =
       
  1780 					 iProcessingFunction.BufferFlushingIndication(
       
  1781 					portIndex,
       
  1782 					pPort->Direction())))
       
  1783 					{
       
  1784 					return omxRetValue;
       
  1785 					}
       
  1786 
       
  1787 				// Inform the port that it is being disabled
       
  1788 				pPort->SetTransitionToDisabled();
       
  1789 				}
       
  1790 			else
       
  1791 				{
       
  1792 				// Inform the port that the disabled command has
       
  1793 				// completed...
       
  1794 				pPort->SetTransitionToDisabledCompleted();
       
  1795 
       
  1796 				// For each disabled port, the IL Client must be notified
       
  1797 				// with a disabled completion event...
       
  1798 				if (OMX_ErrorNone !=
       
  1799 					(omxRetValue =
       
  1800 					 iCallbacks.CommandCompleteNotification(
       
  1801 						 OMX_CommandPortDisable, portIndex)))
       
  1802 					{
       
  1803 					return omxRetValue;
       
  1804 					}
       
  1805 				}
       
  1806 
       
  1807 			}
       
  1808 
       
  1809 		// Increment loop counter
       
  1810 		++i;
       
  1811 		}
       
  1812 	while(OMX_ALL == aPortIndex && i < portCount);
       
  1813 
       
  1814 	return OMX_ErrorNone;
       
  1815 
       
  1816 	}
       
  1817 
       
  1818 OMX_ERRORTYPE
       
  1819 COmxILPortManager::BufferMarkIndication(
       
  1820 	TUint32 aPortIndex,
       
  1821 	OMX_PTR ipMarkData)
       
  1822 	{
       
  1823     DEBUG_PRINTF2(_L8("COmxILPortManager::BufferMarkIndication: PORT[%d] "), aPortIndex);
       
  1824 
       
  1825 	// Check the index of the port..
       
  1826 	if (CheckPortIndex(aPortIndex) != OMX_ErrorNone)
       
  1827 		{
       
  1828 		return OMX_ErrorBadPortIndex;
       
  1829 		}
       
  1830 
       
  1831 	const OMX_MARKTYPE* pMark = static_cast<OMX_MARKTYPE*>(ipMarkData);
       
  1832 
       
  1833 	if (!pMark->hMarkTargetComponent)
       
  1834 		{
       
  1835 		return OMX_ErrorBadParameter;
       
  1836 		}
       
  1837 
       
  1838 	// Let's tell the port to store the mark so it can mark the next incoming
       
  1839 	// buffer...
       
  1840 	return iAllPorts[aPortIndex]->StoreBufferMark(pMark);
       
  1841 
       
  1842 	}
       
  1843 
       
  1844 OMX_ERRORTYPE
       
  1845 COmxILPortManager::ComponentRoleIndication(TUint aComponentRoleIndex)
       
  1846 	{
       
  1847     DEBUG_PRINTF2(_L8("COmxILPortManager::ComponentRoleIndication : aComponentRoleIndex[%d]"), aComponentRoleIndex);
       
  1848 
       
  1849 	// At this point, the IL Client wants to set the default role that the
       
  1850 	// standard component is assuming. Therefore, the role defaults need to be
       
  1851 	// reloaded into all ports and the processing function object.
       
  1852 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
  1853 	const TInt portCount = iAllPorts.Count();
       
  1854 	for (TUint i = 0; i< portCount; ++i)
       
  1855 		{
       
  1856 		if (OMX_ErrorNone !=
       
  1857 			(omxRetValue =
       
  1858 			 iAllPorts[i]->SetComponentRoleDefaults(aComponentRoleIndex)))
       
  1859 			{
       
  1860 			return omxRetValue;
       
  1861 			}
       
  1862 		}
       
  1863 
       
  1864 	return iProcessingFunction.ComponentRoleIndication(aComponentRoleIndex);
       
  1865 
       
  1866 	}
       
  1867 
       
  1868 OMX_ERRORTYPE
       
  1869 COmxILPortManager::PortSettingsChangeIndication(OMX_U32 aPortIndex,
       
  1870 												TUint aPortSettingsIndex,
       
  1871 												const TDesC8& aPortSettings,
       
  1872 												OMX_EVENTTYPE& aEventForILClient)
       
  1873 	{
       
  1874     DEBUG_PRINTF2(_L8("COmxILPortManager::PortSettingsChangeIndication: PORT[%d] "), aPortIndex);
       
  1875 
       
  1876 	// Check the index of the port..
       
  1877 	if (CheckPortIndex(aPortIndex) != OMX_ErrorNone)
       
  1878 		{
       
  1879 		return OMX_ErrorBadPortIndex;
       
  1880 		}
       
  1881 
       
  1882 	return iAllPorts[aPortIndex]->DoPortReconfiguration(
       
  1883 		aPortSettingsIndex, aPortSettings, aEventForILClient);
       
  1884 
       
  1885 	}
       
  1886 
       
  1887 
       
  1888 TBool
       
  1889 COmxILPortManager::AllPortsPopulated() const
       
  1890 	{
       
  1891 
       
  1892 	const TInt portCount = iAllPorts.Count();
       
  1893 	COmxILPort* pPort = 0;
       
  1894 	for (TInt i=0; i<portCount; ++i)
       
  1895 		{
       
  1896 		pPort = iAllPorts[i];
       
  1897 		if (!pPort->IsEnabled())
       
  1898 			{
       
  1899 			continue;
       
  1900 			}
       
  1901 
       
  1902 		if (!pPort->IsPopulated())
       
  1903 			{
       
  1904 			DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsPopulated : [FALSE]"));
       
  1905 			return EFalse;
       
  1906 			}
       
  1907 		}
       
  1908 
       
  1909 	DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsPopulated : [TRUE]"));
       
  1910 	return ETrue;
       
  1911 
       
  1912 	}
       
  1913 
       
  1914 TBool
       
  1915 COmxILPortManager::AllPortsDePopulated() const
       
  1916 	{
       
  1917 
       
  1918 	const TInt portCount = iAllPorts.Count();
       
  1919 	for (TInt i=0; i<portCount; ++i)
       
  1920 		{
       
  1921 		if (!iAllPorts[i]->IsDePopulated())
       
  1922 			{
       
  1923 			DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsDePopulated : [FALSE]"));
       
  1924 			return EFalse;
       
  1925 			}
       
  1926 		}
       
  1927 
       
  1928 	DEBUG_PRINTF(_L8("COmxILPortManager::AllPortsDePopulated : [TRUE]"));
       
  1929 	return ETrue;
       
  1930 
       
  1931 	}
       
  1932 
       
  1933 TBool
       
  1934 COmxILPortManager::AllBuffersAtHome() const
       
  1935 	{
       
  1936 
       
  1937 	const TInt portCount = iAllPorts.Count();
       
  1938 	for (TInt i=0; i<portCount; ++i)
       
  1939 		{
       
  1940 		if (iAllPorts[i]->IsTunnelledAndBufferSupplier())
       
  1941 			{
       
  1942 			if (!iAllPorts[i]->HasAllBuffersAtHome())
       
  1943 				{
       
  1944 				DEBUG_PRINTF(_L8("COmxILPortManager::AllBuffersAtHome : [FALSE]"));
       
  1945 				return EFalse;
       
  1946 				}
       
  1947 			}
       
  1948 		}
       
  1949 
       
  1950 	DEBUG_PRINTF(_L8("COmxILPortManager::AllBuffersAtHome : [TRUE]"));
       
  1951 	return ETrue;
       
  1952 
       
  1953 	}