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