omxil_generic/omxilcomplib/src/omxilportimpl.cpp
changeset 0 0e4a32b9112d
equal deleted inserted replaced
-1:000000000000 0:0e4a32b9112d
       
     1 // Copyright (c) 2010 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 <mmf/server/mmfbuffer.h>
       
    23 #include <mmf/server/mmfdatabuffer.h>
       
    24 
       
    25 #include "log.h"
       
    26 #include "omxilportimpl.h"
       
    27 #include <openmax/il/common/omxilport.h>
       
    28 #include <openmax/il/common/omxilutil.h>
       
    29 
       
    30 const TInt COmxILPortImpl::KMaxBufferMarksQueueSize;
       
    31 
       
    32 COmxILPortImpl* COmxILPortImpl::NewL(const TOmxILCommonPortData& aCommonPortData, COmxILPort& aPort)
       
    33 	{
       
    34 	COmxILPortImpl* self = new (ELeave) COmxILPortImpl(aCommonPortData, aPort);
       
    35 	return self;	
       
    36 	}
       
    37 
       
    38 COmxILPortImpl::COmxILPortImpl(const TOmxILCommonPortData& aCommonPortData, COmxILPort& aPort)
       
    39 	:
       
    40 	iTunnelledComponent(0),
       
    41 	iTunnelledPort(0),
       
    42 	iBufferHeaders(),
       
    43 	iBufferMarks(_FOFF(TBufferMarkInfo, iLink)),
       
    44 	iTransitionState(EPortNotTransitioning),
       
    45 	iBufferMarkPropagationPortIndex(aCommonPortData.iBufferMarkPropagationPortIndex),
       
    46 	aFirstUseBufferHasBeenReceived(OMX_FALSE),
       
    47 	iOmxILPort(aPort)
       
    48 	{
       
    49     DEBUG_PRINTF(_L8("COmxILPortImpl::COmxILPortImpl"));
       
    50 
       
    51 	// Filll in OMX_PARAM_PORTDEFINITIONTYPE
       
    52 	iParamPortDefinition.nSize				= sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
       
    53 	iParamPortDefinition.nVersion			= aCommonPortData.iOmxVersion;
       
    54 	iParamPortDefinition.nPortIndex			= aCommonPortData.iPortIndex;
       
    55 	iParamPortDefinition.eDir				= aCommonPortData.iDirection;
       
    56 	iParamPortDefinition.nBufferCountActual = aCommonPortData.iBufferCountMin;
       
    57 	iParamPortDefinition.nBufferCountMin	= aCommonPortData.iBufferCountMin;
       
    58 	iParamPortDefinition.nBufferSize		= aCommonPortData.iBufferSizeMin;
       
    59 	iParamPortDefinition.bEnabled			= OMX_TRUE;
       
    60 	iParamPortDefinition.bPopulated			= OMX_FALSE;
       
    61 	iParamPortDefinition.eDomain			= aCommonPortData.iPortDomain;
       
    62 	// NOTE: iParamPortDefinition.format must be finished up by concrete ports
       
    63 	iParamPortDefinition.bBuffersContiguous = aCommonPortData.iBuffersContiguous;
       
    64 	iParamPortDefinition.nBufferAlignment	= aCommonPortData.iBufferAlignment;
       
    65 
       
    66 	// Fill in OMX_PARAM_BUFFERSUPPLIERTYPE
       
    67 	iParamCompBufferSupplier.nSize			 = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
       
    68 	iParamCompBufferSupplier.nVersion		 = aCommonPortData.iOmxVersion;
       
    69 	iParamCompBufferSupplier.nPortIndex		 = aCommonPortData.iPortIndex;
       
    70 	iParamCompBufferSupplier.eBufferSupplier = aCommonPortData.iBufferSupplier;
       
    71 
       
    72 	}
       
    73 
       
    74 COmxILPortImpl::~COmxILPortImpl()
       
    75 	{
       
    76     DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl"));
       
    77 
       
    78 #ifdef _DEBUG
       
    79 	const TInt headerCount = iBufferHeaders.Count();
       
    80 	if (headerCount > 0)
       
    81 		{
       
    82 		DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl :: ------------------------------- WARNING ---------------------------------------  "));
       
    83 		DEBUG_PRINTF2(_L8("COmxILPortImpl::~COmxILPortImpl :: [%d] Buffer headers still exist"), headerCount);
       
    84 		DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl :: CleanUpPort() may be used from the most derived port class to delete them"));
       
    85 		DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl :: ------------------------------- WARNING ---------------------------------------  "));
       
    86 		}
       
    87 #endif
       
    88 
       
    89 	iBufferHeaders.Close();
       
    90 	iBufferMarks.ResetAndDestroy();
       
    91 
       
    92 	}
       
    93 
       
    94 OMX_ERRORTYPE
       
    95 COmxILPortImpl::GetParameter(OMX_INDEXTYPE aParamIndex,
       
    96 						 TAny* apComponentParameterStructure) const
       
    97 	{
       
    98     DEBUG_PRINTF(_L8("COmxILPortImpl::GetParameter"));
       
    99 
       
   100 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   101 	switch(aParamIndex)
       
   102 		{
       
   103 	case OMX_IndexParamPortDefinition:
       
   104 		{
       
   105 		if (OMX_ErrorNone != (omxRetValue =
       
   106 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   107 								  apComponentParameterStructure,
       
   108 								  sizeof(OMX_PARAM_PORTDEFINITIONTYPE))))
       
   109 			{
       
   110 			return omxRetValue;
       
   111 			}
       
   112 
       
   113 		OMX_PARAM_PORTDEFINITIONTYPE* pPortDefinition
       
   114 			= static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(
       
   115 				apComponentParameterStructure);
       
   116 
       
   117 		*pPortDefinition = iParamPortDefinition;
       
   118 		}
       
   119 		break;
       
   120 
       
   121 	case OMX_IndexParamCompBufferSupplier:
       
   122 		{
       
   123 		if (OMX_ErrorNone != (omxRetValue =
       
   124 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   125 								  apComponentParameterStructure,
       
   126 								  sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE))))
       
   127 			{
       
   128 			return omxRetValue;
       
   129 			}
       
   130 
       
   131 		OMX_PARAM_BUFFERSUPPLIERTYPE* pBufferSupplier
       
   132 			= static_cast<OMX_PARAM_BUFFERSUPPLIERTYPE*>(
       
   133 				apComponentParameterStructure);
       
   134 
       
   135 		pBufferSupplier->eBufferSupplier =
       
   136 			iParamCompBufferSupplier.eBufferSupplier;
       
   137 		}
       
   138 		break;
       
   139 
       
   140 	default:
       
   141 		{
       
   142 		return OMX_ErrorUnsupportedIndex;
       
   143 		}
       
   144 		};
       
   145 
       
   146 	return OMX_ErrorNone;
       
   147 
       
   148 	}
       
   149 
       
   150 OMX_ERRORTYPE
       
   151 COmxILPortImpl::SetParameter(OMX_INDEXTYPE aParamIndex,
       
   152 						 const TAny* apComponentParameterStructure,
       
   153 						 TBool& aUpdateProcessingFunction)
       
   154 	{
       
   155     DEBUG_PRINTF(_L8("COmxILPortImpl::SetParameter"));
       
   156 
       
   157 	aUpdateProcessingFunction = EFalse;
       
   158 
       
   159 
       
   160 	if (OMX_TRUE == aFirstUseBufferHasBeenReceived)
       
   161 		{
       
   162 		DEBUG_PRINTF2(_L8("COmxILPortImpl::SetParameter : PORT [%u] WARNING : port population already initiated, returning OMX_ErrorIncorrectStateOperation"), Index());
       
   163 		// SetParameter is not allowed after the first OMX_UseBuffer has been
       
   164 		// received in the port, that is, the population of the port has
       
   165 		// already been initiated...
       
   166 		return OMX_ErrorIncorrectStateOperation;
       
   167 		}
       
   168 
       
   169 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   170 
       
   171 	switch(aParamIndex)
       
   172 		{
       
   173 	case OMX_IndexParamPortDefinition:
       
   174 		{
       
   175 		if (OMX_ErrorNone != (omxRetValue =
       
   176 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   177 								  const_cast<OMX_PTR>(apComponentParameterStructure),
       
   178 								  sizeof(OMX_PARAM_PORTDEFINITIONTYPE))))
       
   179 			{
       
   180 			return omxRetValue;
       
   181 			}
       
   182 
       
   183 		const OMX_PARAM_PORTDEFINITIONTYPE* pPortDefinition
       
   184 			= static_cast<const OMX_PARAM_PORTDEFINITIONTYPE*>(
       
   185 				apComponentParameterStructure);
       
   186 
       
   187 		// Port Format must be set by the concrete port...
       
   188 		if (OMX_ErrorNone !=
       
   189 			(omxRetValue =
       
   190 			 iOmxILPort.SetFormatInPortDefinition(*pPortDefinition,
       
   191 									   aUpdateProcessingFunction)))
       
   192 			{
       
   193 			return omxRetValue;
       
   194 			}
       
   195 
       
   196 		// Set here only the additional read-write parameters of
       
   197 		// OMX_PARAM_PORTDEFINITIONTYPE
       
   198 		if (iParamPortDefinition.nBufferCountActual !=
       
   199 			pPortDefinition->nBufferCountActual)
       
   200 			{
       
   201 			if (pPortDefinition->nBufferCountActual <
       
   202 				iParamPortDefinition.nBufferCountMin)
       
   203 				{
       
   204 				return OMX_ErrorBadParameter;
       
   205 				}
       
   206 			DEBUG_PRINTF3(_L8("COmxILPortImpl::SetParameter : old.nBufferCountActual [%u] new.nBufferCountActual [%u]"),
       
   207 						  iParamPortDefinition.nBufferCountActual, pPortDefinition->nBufferCountActual);
       
   208 			iParamPortDefinition.nBufferCountActual =
       
   209 				pPortDefinition->nBufferCountActual;
       
   210 			aUpdateProcessingFunction = ETrue;
       
   211 			}
       
   212 
       
   213 		}
       
   214 		break;
       
   215 
       
   216 	case OMX_IndexParamCompBufferSupplier:
       
   217 		{
       
   218 		if (OMX_ErrorNone != (omxRetValue =
       
   219 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   220 								  const_cast<OMX_PTR>(apComponentParameterStructure),
       
   221 								  sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE))))
       
   222 			{
       
   223 			return omxRetValue;
       
   224 			}
       
   225 
       
   226 		const OMX_PARAM_BUFFERSUPPLIERTYPE* pBufferSupplier
       
   227 			= static_cast<const OMX_PARAM_BUFFERSUPPLIERTYPE*>(
       
   228 				apComponentParameterStructure);
       
   229 
       
   230 		// OMX_BufferSupplyOutput is the last of the supported values as of
       
   231 		// v1.1.1
       
   232 		if (iParamCompBufferSupplier.eBufferSupplier > OMX_BufferSupplyOutput)
       
   233 			{
       
   234 			return OMX_ErrorBadParameter;
       
   235 			}
       
   236 
       
   237 		if (iParamCompBufferSupplier.eBufferSupplier !=
       
   238 			pBufferSupplier->eBufferSupplier)
       
   239 			{
       
   240 			// The component providing the input port is responsible for
       
   241 			// signalling the tunnelled component about the buffer supplier
       
   242 			// override...
       
   243 			if (iTunnelledComponent &&
       
   244 				iParamPortDefinition.eDir == OMX_DirInput)
       
   245 				{
       
   246 				OMX_PARAM_BUFFERSUPPLIERTYPE bufferSupplierType;
       
   247 				bufferSupplierType.nSize		   = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
       
   248 				bufferSupplierType.nVersion		   = iParamPortDefinition.nVersion;
       
   249 				bufferSupplierType.nPortIndex	   = iTunnelledPort;
       
   250 				bufferSupplierType.eBufferSupplier = pBufferSupplier->eBufferSupplier;
       
   251 				OMX_ERRORTYPE retValue = OMX_ErrorUndefined;
       
   252 				if (OMX_ErrorNone !=
       
   253 					(retValue =
       
   254 					 OMX_SetParameter(iTunnelledComponent,
       
   255 									  OMX_IndexParamCompBufferSupplier,
       
   256 									  &bufferSupplierType)) )
       
   257 					{
       
   258 					return retValue;
       
   259 					}
       
   260 				}
       
   261 			DEBUG_PRINTF3(_L8("COmxILPortImpl::SetParameter : old.eBufferSupplier [%u] new.eBufferSupplier [%u]"),
       
   262 						  iParamCompBufferSupplier.eBufferSupplier, pBufferSupplier->eBufferSupplier);
       
   263 			iParamCompBufferSupplier.eBufferSupplier =
       
   264 				pBufferSupplier->eBufferSupplier;
       
   265 			}
       
   266 
       
   267 		}
       
   268 		break;
       
   269 	default:
       
   270 		{
       
   271 		return OMX_ErrorUnsupportedIndex;
       
   272 		}
       
   273 		};
       
   274 
       
   275 	return OMX_ErrorNone;
       
   276 
       
   277 	}
       
   278 
       
   279 OMX_ERRORTYPE
       
   280 COmxILPortImpl::PopulateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr,
       
   281 						   const OMX_PTR apAppPrivate,
       
   282 						   OMX_U32 aSizeBytes,
       
   283 						   OMX_U8* apBuffer,
       
   284 						   TBool& portPopulationCompleted)
       
   285 	{
       
   286 	DEBUG_PRINTF3(_L8("COmxILPort::PopulateBuffer : pBuffer[%X] PORT[%u]"), apBuffer, iParamPortDefinition.nPortIndex);
       
   287 	portPopulationCompleted = EFalse;
       
   288 
       
   289 	if(aSizeBytes < iParamPortDefinition.nBufferSize)
       
   290 		{
       
   291 		return OMX_ErrorBadParameter;
       
   292 		}
       
   293 
       
   294 	// Allocate the buffer header...
       
   295 	OMX_BUFFERHEADERTYPE* pHeader = new OMX_BUFFERHEADERTYPE;
       
   296 	*appBufferHdr = pHeader;
       
   297 	if (!pHeader)
       
   298 		{
       
   299 		return OMX_ErrorInsufficientResources;
       
   300 		}
       
   301 
       
   302     DEBUG_PRINTF2(_L8("COmxILPortImpl::PopulateBuffer : BUFFER [%X]"), pHeader);
       
   303 
       
   304 	// Here, lets discriminate between apBuffer == 0 (AllocateBuffer) and
       
   305 	// apBuffer != 0 (UseBuffer)
       
   306 	TUint8* pPortSpecificBuffer = 0;
       
   307 	OMX_PTR pPortPrivate = 0;
       
   308 	OMX_PTR pPlatformPrivate = 0;
       
   309 	OMX_ERRORTYPE portSpecificErr = OMX_ErrorNone;
       
   310 	if (apBuffer)
       
   311 		{
       
   312 		//... (UseBuffer) Do any port-specific wrapping of the received buffer,
       
   313 		// if needed by the port....
       
   314 		portSpecificErr = iOmxILPort.DoBufferWrapping(aSizeBytes,
       
   315 										   apBuffer,
       
   316 										   pPortPrivate,
       
   317 										   pPlatformPrivate,
       
   318 										   apAppPrivate);
       
   319 
       
   320 		aFirstUseBufferHasBeenReceived = OMX_TRUE;
       
   321 		}
       
   322 	else
       
   323 		{
       
   324 		// ... (AllocateBuffer) Do the port-specific buffer allocation ...
       
   325 		portSpecificErr = iOmxILPort.DoBufferAllocation(aSizeBytes,
       
   326 											 pPortSpecificBuffer,
       
   327 											 pPortPrivate,
       
   328 											 pPlatformPrivate,
       
   329 											 apAppPrivate);
       
   330 		}
       
   331 
       
   332 	if (OMX_ErrorNone != portSpecificErr)
       
   333 		{
       
   334 		delete *appBufferHdr; *appBufferHdr = 0;
       
   335 		return portSpecificErr;
       
   336 		}
       
   337 
       
   338 
       
   339 	// Add to local list of buffer headers...
       
   340 	if (KErrNone !=
       
   341 		iBufferHeaders.Append(
       
   342 			TBufferInfo(pHeader,
       
   343 						(apBuffer ?
       
   344 						 TBufferInfo::EBufferAway :
       
   345 						 TBufferInfo::EBufferAtHome),
       
   346 						(apBuffer ?
       
   347 						 TBufferInfo::EBufferNotOwned :
       
   348 						 TBufferInfo::EBufferOwned),
       
   349 						apBuffer,
       
   350 						apAppPrivate,
       
   351 						pPlatformPrivate,
       
   352 						pPortPrivate)))
       
   353 		{
       
   354 		// Undo custom buffer allocation/wrapping
       
   355 		if (apBuffer)
       
   356 			{
       
   357 			iOmxILPort.DoBufferUnwrapping(
       
   358 				apBuffer,
       
   359 				pPortPrivate,
       
   360 				pPlatformPrivate,
       
   361 				apAppPrivate);
       
   362 
       
   363 			}
       
   364 		else
       
   365 			{
       
   366 			iOmxILPort.DoBufferDeallocation(
       
   367 				pPortSpecificBuffer,
       
   368 				pPortPrivate,
       
   369 				pPlatformPrivate,
       
   370 				apAppPrivate);
       
   371 			}
       
   372 		delete *appBufferHdr; *appBufferHdr = NULL;
       
   373 		return OMX_ErrorInsufficientResources;
       
   374 		}
       
   375 
       
   376 
       
   377 	// Fill in the header...
       
   378 	pHeader->nSize				  = sizeof(OMX_BUFFERHEADERTYPE);
       
   379 	pHeader->nVersion			  = iParamPortDefinition.nVersion;
       
   380 	pHeader->pBuffer			  = apBuffer ? apBuffer : pPortSpecificBuffer;
       
   381 	pHeader->nAllocLen			  = aSizeBytes;
       
   382 	pHeader->nFilledLen			  = 0;
       
   383 	pHeader->nOffset			  = 0;
       
   384 	pHeader->pAppPrivate		  = apAppPrivate;
       
   385 	pHeader->pPlatformPrivate	  = pPlatformPrivate;
       
   386 	pHeader->hMarkTargetComponent = 0;
       
   387 	pHeader->pMarkData			  = 0;
       
   388 	pHeader->nTickCount			  = 0;
       
   389 	pHeader->nTimeStamp			  = 0;
       
   390 	pHeader->nFlags				  = 0;
       
   391 
       
   392 
       
   393 	if (OMX_DirInput == iParamPortDefinition.eDir)
       
   394 		{
       
   395 		pHeader->pInputPortPrivate	= pPortPrivate;
       
   396 		pHeader->pOutputPortPrivate = 0;
       
   397 		pHeader->nInputPortIndex	= iParamPortDefinition.nPortIndex;
       
   398 		pHeader->nOutputPortIndex	= 0;
       
   399 		}
       
   400 	else
       
   401 		{
       
   402 		pHeader->pInputPortPrivate	= 0;
       
   403 		pHeader->pOutputPortPrivate = pPortPrivate;
       
   404 		pHeader->nInputPortIndex	= 0;
       
   405 		pHeader->nOutputPortIndex	= iParamPortDefinition.nPortIndex;
       
   406 		}
       
   407 
       
   408 	if (iParamPortDefinition.nBufferCountActual == iBufferHeaders.Count())
       
   409 		{
       
   410 		iParamPortDefinition.bPopulated = OMX_TRUE;
       
   411 		portPopulationCompleted			= ETrue;
       
   412 		}
       
   413 
       
   414 	return OMX_ErrorNone;
       
   415 
       
   416 	}
       
   417 
       
   418 
       
   419 OMX_ERRORTYPE
       
   420 COmxILPortImpl::FreeBuffer(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   421 					   TBool& portDepopulationCompleted)
       
   422 	{
       
   423     DEBUG_PRINTF2(_L8("COmxILPortImpl::FreeBuffer : BUFFER [%X]"), apBufferHeader);
       
   424 
       
   425 	portDepopulationCompleted = EFalse;
       
   426 
       
   427 	TInt headerIndex = 0;
       
   428 	if (KErrNotFound ==
       
   429 		(headerIndex =
       
   430 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
   431 							 TIdentityRelation<TBufferInfo>(
       
   432 								 &TBufferInfo::Compare))))
       
   433 		{
       
   434 		return OMX_ErrorBadParameter;
       
   435 		}
       
   436 
       
   437 
       
   438 	OMX_PTR pPortPrivate =
       
   439 		OMX_DirInput == iParamPortDefinition.eDir ?
       
   440 		apBufferHeader->pInputPortPrivate :
       
   441 		apBufferHeader->pOutputPortPrivate;
       
   442 
       
   443 	if (iBufferHeaders[headerIndex].IsBufferOwned())
       
   444 		{
       
   445 		iOmxILPort.DoBufferDeallocation(
       
   446 			apBufferHeader->pBuffer,
       
   447 			pPortPrivate,
       
   448 			apBufferHeader->pPlatformPrivate,
       
   449 			apBufferHeader->pAppPrivate);
       
   450 		}
       
   451 	else
       
   452 		{
       
   453 		iOmxILPort.DoBufferUnwrapping(
       
   454 			apBufferHeader->pBuffer,
       
   455 			pPortPrivate,
       
   456 			apBufferHeader->pPlatformPrivate,
       
   457 			apBufferHeader->pAppPrivate);
       
   458 		}
       
   459 
       
   460 	delete apBufferHeader;
       
   461 	iBufferHeaders.Remove(headerIndex);
       
   462 
       
   463 	if (iBufferHeaders.Count() < iParamPortDefinition.nBufferCountActual)
       
   464 		{
       
   465 		iParamPortDefinition.bPopulated = OMX_FALSE;
       
   466 		}
       
   467 
       
   468 	if (0 == iBufferHeaders.Count())
       
   469 		{
       
   470 		portDepopulationCompleted = ETrue;
       
   471 		aFirstUseBufferHasBeenReceived = OMX_FALSE;
       
   472 		}
       
   473 
       
   474 	return OMX_ErrorNone;
       
   475 
       
   476 	}
       
   477 
       
   478 
       
   479 OMX_ERRORTYPE
       
   480 COmxILPortImpl::TunnelRequest(OMX_HANDLETYPE aTunneledComp,
       
   481 						  OMX_U32 aTunneledPort,
       
   482 						  OMX_TUNNELSETUPTYPE* apTunnelSetup)
       
   483 	{
       
   484     DEBUG_PRINTF(_L8("COmxILPortImpl::TunnelRequest"));
       
   485 
       
   486 	// Check whether the tunnel is being torn down
       
   487 	if (!aTunneledComp)
       
   488 		{
       
   489 		// Cancel existing tunnel setup, if any
       
   490 		iTunnelledComponent = 0;
       
   491 		return OMX_ErrorNone;
       
   492 		}
       
   493 
       
   494 	// Check that we are receiving a valid tunnel setup structure
       
   495 	if (!apTunnelSetup)
       
   496 		{
       
   497 		return OMX_ErrorBadParameter;
       
   498 		}
       
   499 
       
   500 	// STEP 0: Retrieve the port definition from the tunnelled component...
       
   501 	OMX_PARAM_PORTDEFINITIONTYPE paramPortDef;
       
   502 	paramPortDef.nSize		= sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
       
   503 	paramPortDef.nVersion	= iParamPortDefinition.nVersion;
       
   504 	paramPortDef.nPortIndex = aTunneledPort;
       
   505 	if (OMX_ErrorNone !=
       
   506 		OMX_GetParameter(aTunneledComp,
       
   507 						 OMX_IndexParamPortDefinition,
       
   508 						 &paramPortDef) )
       
   509 		{
       
   510 		return OMX_ErrorUndefined;
       
   511 		}
       
   512 
       
   513 	if (OMX_DirOutput == iParamPortDefinition.eDir)
       
   514 		{
       
   515 		// OMX_DirOutput
       
   516 		//
       
   517 
       
   518 		// Step 1: Check that this output port is being tunnelled to an input
       
   519 		// port...
       
   520 		if (paramPortDef.eDir != OMX_DirInput)
       
   521 			{
       
   522 			return OMX_ErrorPortsNotCompatible;
       
   523 			}
       
   524 
       
   525 		// Step 2: Fill in the tunnel setup structure received...
       
   526 		apTunnelSetup->nTunnelFlags = 0;
       
   527 		apTunnelSetup->eSupplier	= iParamCompBufferSupplier.eBufferSupplier;
       
   528 
       
   529 		iTunnelledComponent	= aTunneledComp;
       
   530 		iTunnelledPort		= aTunneledPort;
       
   531 		}
       
   532 	else
       
   533 		{
       
   534 		// OMX_DirInput
       
   535 		//
       
   536 
       
   537 		// Check that this input port is being tunnelled to an output
       
   538 		// port...
       
   539 		if (paramPortDef.eDir != OMX_DirOutput)
       
   540 			{
       
   541 			return OMX_ErrorPortsNotCompatible;
       
   542 			}
       
   543 
       
   544 		// Check that there is something consistent in the tunnel setup data
       
   545 		// received...
       
   546 		if ((apTunnelSetup->eSupplier != OMX_BufferSupplyUnspecified) &&
       
   547 			(apTunnelSetup->eSupplier != OMX_BufferSupplyInput) &&
       
   548 			(apTunnelSetup->eSupplier != OMX_BufferSupplyOutput))
       
   549 			{
       
   550 			return OMX_ErrorBadParameter;
       
   551 			}
       
   552 
       
   553 		// Set tunnelled component and port as they will be needed by
       
   554 		// IsTunnelledPortCompatible...
       
   555 		iTunnelledComponent	= aTunneledComp;
       
   556 		iTunnelledPort		= aTunneledPort;
       
   557 
       
   558 		// Check domain-specific parameter compatibility (this is delegated
       
   559 		// to derived port classes)...
       
   560 		if (!iOmxILPort.IsTunnelledPortCompatible(paramPortDef))
       
   561 			{
       
   562 			iTunnelledComponent	= 0;
       
   563 			return OMX_ErrorPortsNotCompatible;
       
   564 			}
       
   565 
       
   566 		// Now, try to get to an understanding here...Work out which port will
       
   567 		// be buffer supplier...
       
   568 		OMX_BUFFERSUPPLIERTYPE bufferSupplierDecision =
       
   569 			OMX_BufferSupplyUnspecified;
       
   570 		if (apTunnelSetup->nTunnelFlags & OMX_PORTTUNNELFLAG_READONLY	||
       
   571 			( (apTunnelSetup->eSupplier == OMX_BufferSupplyInput) &&
       
   572 			  (iParamCompBufferSupplier.eBufferSupplier ==
       
   573 			   OMX_BufferSupplyInput ||
       
   574 			   iParamCompBufferSupplier.eBufferSupplier ==
       
   575 			   OMX_BufferSupplyUnspecified) ) ||
       
   576 			( (apTunnelSetup->eSupplier == OMX_BufferSupplyUnspecified) &&
       
   577 			  (iParamCompBufferSupplier.eBufferSupplier ==
       
   578 			   OMX_BufferSupplyInput)) )
       
   579 			{
       
   580 			bufferSupplierDecision = OMX_BufferSupplyInput;
       
   581 			}
       
   582 		else
       
   583 			{
       
   584 			bufferSupplierDecision = OMX_BufferSupplyOutput;
       
   585 			}
       
   586 
       
   587 		// Set buffer supplier param in tunnelled port...
       
   588 		OMX_PARAM_BUFFERSUPPLIERTYPE bufferSupplierType;
       
   589 		bufferSupplierType.nSize		   = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
       
   590 		bufferSupplierType.nVersion		   = iParamPortDefinition.nVersion;
       
   591 		bufferSupplierType.nPortIndex	   = aTunneledPort;
       
   592 		bufferSupplierType.eBufferSupplier = bufferSupplierDecision;
       
   593 		if (OMX_ErrorNone !=
       
   594 			OMX_SetParameter(aTunneledComp,
       
   595 							 OMX_IndexParamCompBufferSupplier,
       
   596 							 &bufferSupplierType) )
       
   597 			{
       
   598 			iTunnelledComponent = 0;
       
   599 			return OMX_ErrorPortsNotCompatible;
       
   600 			}
       
   601 
       
   602 		apTunnelSetup->eSupplier = bufferSupplierDecision;
       
   603 		iParamCompBufferSupplier.eBufferSupplier = bufferSupplierDecision;
       
   604 
       
   605 		}
       
   606 
       
   607 	return OMX_ErrorNone;
       
   608 
       
   609 	}
       
   610 
       
   611 
       
   612 OMX_ERRORTYPE
       
   613 COmxILPortImpl::PopulateTunnel(TBool& portPopulationCompleted)
       
   614 	{
       
   615     DEBUG_PRINTF(_L8("COmxILPortImpl::PopulateTunnel"));
       
   616 
       
   617 	__ASSERT_DEBUG(iBufferHeaders.Count() == 0,
       
   618 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   619 	__ASSERT_DEBUG(IsTunnelledAndBufferSupplier(),
       
   620 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   621 
       
   622 	portPopulationCompleted = EFalse;
       
   623 
       
   624 	// STEP 1: Obtain the number of buffers that the tunnelled port requires to
       
   625 	// be populated...  Retrieve the port definition from the tunnelled
       
   626 	// component
       
   627 	OMX_PARAM_PORTDEFINITIONTYPE paramPortDef;
       
   628 	paramPortDef.nSize		= sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
       
   629 	paramPortDef.nVersion	= iParamPortDefinition.nVersion;
       
   630 	paramPortDef.nPortIndex = iTunnelledPort;
       
   631 	if (OMX_ErrorNone !=
       
   632 		OMX_GetParameter(iTunnelledComponent,
       
   633 						 OMX_IndexParamPortDefinition,
       
   634 						 &paramPortDef) )
       
   635 		{
       
   636 		return OMX_ErrorUndefined;
       
   637 		}
       
   638 
       
   639 	// Step 2: Both ports must have the same threshold value (number of buffers
       
   640 	// to be populated) before completing the transition to
       
   641 	// OMX_StateIdle...Otherwise the population process would complete earlier
       
   642 	// or never...
       
   643 	TUint numOfBuffersToPopulate = iParamPortDefinition.nBufferCountActual;
       
   644 	if(paramPortDef.nBufferCountActual !=
       
   645 	   iParamPortDefinition.nBufferCountActual)
       
   646 		{
       
   647 		numOfBuffersToPopulate =
       
   648 			Max(iParamPortDefinition.nBufferCountActual,
       
   649 				paramPortDef.nBufferCountActual);
       
   650 		if (iParamPortDefinition.nBufferCountActual <
       
   651 			numOfBuffersToPopulate)
       
   652 			{
       
   653 			// Update own buffer count requirements
       
   654 			DEBUG_PRINTF3(_L8("COmxILPortImpl::PopulateTunnel : Updated own nBufferCountActual - Old Value [%d] New Value [%d] "),
       
   655 						  iParamPortDefinition.nBufferCountActual, numOfBuffersToPopulate);
       
   656 			iParamPortDefinition.nBufferCountActual = numOfBuffersToPopulate;
       
   657 			}
       
   658 		else
       
   659 			{
       
   660 			// Update peer's buffer count requirements
       
   661 			DEBUG_PRINTF3(_L8("COmxILPortImpl::PopulateTunnel : Updated peer's nBufferCountActual - Old Value [%d] New Value [%d] "),
       
   662 						  paramPortDef.nBufferCountActual, numOfBuffersToPopulate);
       
   663 			paramPortDef.nBufferCountActual = numOfBuffersToPopulate;
       
   664 			if (OMX_ErrorNone != OMX_SetParameter(iTunnelledComponent,
       
   665 												  OMX_IndexParamPortDefinition,
       
   666 												  &paramPortDef))
       
   667 				{
       
   668 				DEBUG_PRINTF(_L8("COmxILPortImpl::PopulateTunnel : Error setting nBufferCountActual in tunnelled component "));
       
   669 				return OMX_ErrorUndefined;
       
   670 				}
       
   671 			}
       
   672 		}
       
   673 
       
   674 	// STEP 3: Start population of the tunnel...
       
   675 	TUint sizeOfBuffersToPopulate =
       
   676 		iParamPortDefinition.nBufferSize >= paramPortDef.nBufferSize  ?
       
   677 		iParamPortDefinition.nBufferSize :
       
   678 		paramPortDef.nBufferSize;
       
   679 
       
   680 	OMX_BUFFERHEADERTYPE* pHeader = 0;
       
   681 	TUint8* pPortSpecificBuffer = 0;
       
   682 	OMX_PTR pPortPrivate = 0;
       
   683 	OMX_PTR pPlatformPrivate = 0;
       
   684 	OMX_ERRORTYPE portSpecificErr = OMX_ErrorNone;
       
   685 	for (TUint i=0; i<numOfBuffersToPopulate; i++)
       
   686 		{
       
   687 		// Allocate the buffer...
       
   688 		if (OMX_ErrorNone !=
       
   689 			(portSpecificErr = iOmxILPort.DoBufferAllocation(
       
   690 				sizeOfBuffersToPopulate,
       
   691 				pPortSpecificBuffer,
       
   692 				pPortPrivate,
       
   693 				pPlatformPrivate)))
       
   694 			{
       
   695 			// There's no point on continuing here... the tunnel will never
       
   696 			// be completely populated now...
       
   697 			return portSpecificErr;
       
   698 			}
       
   699 		
       
   700 		OMX_ERRORTYPE useBufRes = iOmxILPort.DoOmxUseBuffer(iTunnelledComponent,
       
   701 												 &pHeader,
       
   702 												 iTunnelledPort,
       
   703 												 pPortPrivate,
       
   704 												 pPlatformPrivate,
       
   705 												 sizeOfBuffersToPopulate,
       
   706 												 pPortSpecificBuffer);
       
   707 
       
   708 		if ((OMX_ErrorNone != useBufRes) || !pHeader)
       
   709 			{
       
   710 			iOmxILPort.DoBufferDeallocation(
       
   711 				pPortSpecificBuffer,
       
   712 				pPortPrivate,
       
   713 				pPlatformPrivate);
       
   714 
       
   715 			if (pHeader)
       
   716 				{
       
   717 				switch(useBufRes)
       
   718 					{
       
   719 				case OMX_ErrorIncorrectStateOperation:
       
   720 					{
       
   721 					// Here, the tunnelled component is not ready. Probably,
       
   722 					// the IL Client has not commanded yet the component to go
       
   723 					// to OMX_StateIdle. Out-of-context implementations could
       
   724 					// do here a backoff-and-retry procedure. This
       
   725 					// implementation can just return and expect that the IL
       
   726 					// Client will detect the situation of this component not
       
   727 					// transitioning to OMX_StateIdle.
       
   728 					DEBUG_PRINTF(_L8("COmxILPortImpl::PopulateTunnel : OMX_ErrorIncorrectStateOperation received from non-supplier component"));
       
   729 					}
       
   730 					break;
       
   731 					};
       
   732 				}
       
   733 				
       
   734 			if (OMX_ErrorInsufficientResources == useBufRes)
       
   735 				{
       
   736 				return OMX_ErrorInsufficientResources; 
       
   737 				}
       
   738 			// This is a gotcha. Here there is some problem with the tunnelled
       
   739 			// component. If we return the received error, this component may
       
   740 			// be sending back some error code that is not allowed in
       
   741 			// OMX_SendCommand. Example: The component conformance suite
       
   742 			// expects here OMX_ErrorNone if the tunnelled component does not
       
   743 			// support OMX_UseBuffer or some other problem. Also, we don't send
       
   744 			// and error event here as there's no appropriate error for this
       
   745 			// situation (OMX_ErrorPortUnresponsiveDuringAllocation is for
       
   746 			// non-supplier ports). Therefore, the IL Client should recover
       
   747 			// from this situation after some time by detecting that this
       
   748 			// component didn't transition to OMX_StateIdle.
       
   749 					
       
   750 			return OMX_ErrorNone;
       
   751 			}
       
   752 		// Fill the data in the received header so we can correctly use it when
       
   753 		// the header is at this side of the tunnel...
       
   754 		if (OMX_DirInput == iParamPortDefinition.eDir)
       
   755 			{
       
   756 			pHeader->pInputPortPrivate = pPortPrivate;
       
   757 			pHeader->nInputPortIndex   = iParamPortDefinition.nPortIndex;
       
   758 			}
       
   759 		else	// OMX_DirOutput == iParamPortDefinition.eDir
       
   760 			{
       
   761 			pHeader->pOutputPortPrivate = pPortPrivate;
       
   762 			pHeader->nOutputPortIndex	= iParamPortDefinition.nPortIndex;
       
   763 			}
       
   764 
       
   765 		// Add to local list of buffer headers... return if not sucessful...
       
   766 		if (KErrNone !=
       
   767 			iBufferHeaders.Append(
       
   768 				TBufferInfo(pHeader,
       
   769 							TBufferInfo::EBufferAtHome,
       
   770 							TBufferInfo::EBufferOwned,
       
   771 							pPortSpecificBuffer,
       
   772 							0,
       
   773 							pPlatformPrivate,
       
   774 							pPortPrivate)))
       
   775 			{
       
   776 			iOmxILPort.DoBufferDeallocation(
       
   777 				pPortSpecificBuffer,
       
   778 				pPortPrivate,
       
   779 				pPlatformPrivate);
       
   780 
       
   781 			return OMX_ErrorInsufficientResources;
       
   782 			}
       
   783 		}
       
   784 
       
   785 	iParamPortDefinition.bPopulated = OMX_TRUE;
       
   786 	portPopulationCompleted			= ETrue;
       
   787 
       
   788 	__ASSERT_DEBUG(iBufferHeaders.Count()	  ==
       
   789 				   iParamPortDefinition.nBufferCountActual,
       
   790 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   791 
       
   792 	return OMX_ErrorNone;
       
   793 
       
   794 	}
       
   795 
       
   796 
       
   797 OMX_ERRORTYPE
       
   798 COmxILPortImpl::FreeTunnel(TBool& portDepopulationCompleted)
       
   799 	{
       
   800     DEBUG_PRINTF(_L8("COmxILPortImpl::FreeTunnel"));
       
   801 
       
   802   	__ASSERT_DEBUG(iBufferHeaders.Count() ==
       
   803   				   iParamPortDefinition.nBufferCountActual,
       
   804   				   User::Panic(KOmxILPortPanicCategory, 1));	
       
   805 	
       
   806 	__ASSERT_DEBUG(IsTunnelledAndBufferSupplier(),
       
   807 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   808 
       
   809 	const TUint numBuffersToDepopulate = iBufferHeaders.Count();
       
   810 	for (TUint i=0; i<numBuffersToDepopulate; ++i)
       
   811 		{
       
   812 		OMX_BUFFERHEADERTYPE* pBufferHeader = iBufferHeaders[i].GetHeader();
       
   813 
       
   814 		// Take some things from the header, before it gets deleted by the
       
   815 		// tunnelled port...
       
   816 		OMX_U8* pBuffer = pBufferHeader->pBuffer;
       
   817 		OMX_PTR pPortPrivate =
       
   818 			OMX_DirInput == iParamPortDefinition.eDir ?
       
   819 			pBufferHeader->pInputPortPrivate :
       
   820 			pBufferHeader->pOutputPortPrivate;
       
   821 		OMX_PTR pAppPrivate = pBufferHeader->pAppPrivate;
       
   822 		OMX_PTR pPlatformPrivate = pBufferHeader->pPlatformPrivate;
       
   823 
       
   824 		DEBUG_PRINTF2(_L8("COmxILPortImpl::FreeTunnel : BUFFER [%X]"), iBufferHeaders[i].GetHeader());
       
   825 
       
   826 		OMX_ERRORTYPE freeBufRes = OMX_FreeBuffer(
       
   827 			iTunnelledComponent,
       
   828 			iTunnelledPort,
       
   829 			pBufferHeader);
       
   830 
       
   831 		// At this point, the actual buffer header should no longer exist...
       
   832 		pBufferHeader = 0;
       
   833 
       
   834 		// NOTE that we don't check OMX_FreeBuffer returned error here. If
       
   835 		// something wrong happens at the tunnelled component side we'll
       
   836 		// continue here and try to free as many buffers as possible.... at
       
   837 		// least the state of this component will remain valid.... (we don't
       
   838 		// report errors coming from the tunnelled component as that is its
       
   839 		// responsibility....)
       
   840 
       
   841 		iOmxILPort.DoBufferDeallocation(
       
   842 			pBuffer,
       
   843 			pPortPrivate,
       
   844 			pPlatformPrivate,
       
   845 			pAppPrivate);
       
   846 		}
       
   847 
       
   848 	// Clear the local list of headers. Note that there's no need to delete the
       
   849 	// header as these have been allocated by the tunnelled port...
       
   850 
       
   851 	iBufferHeaders.Reset();
       
   852 	iParamPortDefinition.bPopulated = OMX_FALSE;
       
   853 	portDepopulationCompleted = ETrue;
       
   854 
       
   855 	__ASSERT_DEBUG(iBufferHeaders.Count() == 0,
       
   856 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   857 
       
   858 	return OMX_ErrorNone;
       
   859 
       
   860 	}
       
   861 
       
   862 
       
   863 
       
   864 TBool
       
   865 COmxILPortImpl::SetBufferSent(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   866 						  TBool& aBufferMarkedWithOwnMark)
       
   867 	{
       
   868     DEBUG_PRINTF(_L8("COmxILPortImpl::SetBufferSent"));
       
   869 
       
   870 	__ASSERT_DEBUG(apBufferHeader, User::Panic(KOmxILPortPanicCategory, 1));
       
   871 
       
   872 	aBufferMarkedWithOwnMark = EFalse;
       
   873 
       
   874 	TInt index = 0;
       
   875 	if (KErrNotFound ==
       
   876 		(index =
       
   877 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
   878 							 TIdentityRelation<TBufferInfo>(
       
   879 								 &TBufferInfo::Compare))))
       
   880 		{
       
   881 		return EFalse;
       
   882 		}
       
   883 
       
   884 	iBufferHeaders[index].SetBufferAway();
       
   885 
       
   886 	if (!iBufferMarks.IsEmpty())
       
   887 		{
       
   888 		// Check for existing marks in the buffer header...
       
   889 		if (apBufferHeader->hMarkTargetComponent)
       
   890 			{
       
   891 			// We queue the mark received within the buffer header if there are
       
   892 			// marks already to be delivered... it is mandatory to give a FIFO
       
   893 			// preference to the marks received by a port..
       
   894 			if (iBufferMarks.Elements() < KMaxBufferMarksQueueSize)
       
   895 				{
       
   896 				// The buffer is marked already. Store the current mark at the end
       
   897 				// of the buffer mark list...
       
   898 				StoreBufferMark(apBufferHeader->hMarkTargetComponent,
       
   899 								apBufferHeader->pMarkData);
       
   900 				}
       
   901 			}
       
   902 
       
   903 		// Use the first mark in the queue...
       
   904 		TBufferMarkInfo* pMark = iBufferMarks.First();
       
   905 		apBufferHeader->hMarkTargetComponent = pMark->ipMarkTargetComponent;
       
   906 		apBufferHeader->pMarkData			 = pMark->ipMarkData;
       
   907 		aBufferMarkedWithOwnMark			 = pMark->iOwnMark;
       
   908 		iBufferMarks.Remove(*pMark);
       
   909 		delete pMark;
       
   910 		}
       
   911 
       
   912 	return ETrue;
       
   913 
       
   914 	}
       
   915 
       
   916 TBool
       
   917 COmxILPortImpl::SetBufferReturned(OMX_BUFFERHEADERTYPE* apBufferHeader)
       
   918 	{
       
   919     DEBUG_PRINTF(_L8("COmxILPortImpl::SetBufferReturned"));
       
   920 
       
   921 	__ASSERT_DEBUG(apBufferHeader, User::Panic(KOmxILPortPanicCategory, 1));
       
   922 
       
   923 	TInt index = 0;
       
   924 	if (KErrNotFound ==
       
   925 		(index =
       
   926 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
   927 							 TIdentityRelation<TBufferInfo>(
       
   928 								 &TBufferInfo::Compare))))
       
   929 		{
       
   930 		return EFalse;
       
   931 		}
       
   932 
       
   933 	iBufferHeaders[index].SetBufferAtHome();
       
   934 
       
   935 	return ETrue;
       
   936 
       
   937 	}
       
   938 
       
   939 void
       
   940 COmxILPortImpl::SetTransitionToEnabled()
       
   941 	{
       
   942     DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToEnabled"));
       
   943 
       
   944 	iTransitionState = EPortTransitioningToEnabled;
       
   945 	iParamPortDefinition.bEnabled = OMX_TRUE;
       
   946 
       
   947 	}
       
   948 
       
   949 void
       
   950 COmxILPortImpl::SetTransitionToDisabled()
       
   951 	{
       
   952     DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToDisabled"));
       
   953 
       
   954 	iTransitionState = EPortTransitioningToDisabled;
       
   955 	iParamPortDefinition.bEnabled = OMX_FALSE;
       
   956 
       
   957 	}
       
   958 
       
   959 void
       
   960 COmxILPortImpl::SetTransitionToDisabledCompleted()
       
   961 	{
       
   962     DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToDisabledCompleted"));
       
   963 
       
   964 	iTransitionState = EPortNotTransitioning;
       
   965 	iParamPortDefinition.bEnabled = OMX_FALSE;
       
   966 
       
   967 	}
       
   968 
       
   969 void
       
   970 COmxILPortImpl::SetTransitionToEnabledCompleted()
       
   971 	{
       
   972     DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToEnabledCompleted"));
       
   973 
       
   974 	iTransitionState = EPortNotTransitioning;
       
   975 	iParamPortDefinition.bEnabled = OMX_TRUE;
       
   976 
       
   977 	}
       
   978 
       
   979 OMX_ERRORTYPE
       
   980 COmxILPortImpl::StoreBufferMark(const OMX_MARKTYPE* apMark)
       
   981 	{
       
   982     DEBUG_PRINTF(_L8("COmxILPortImpl::StoreBufferMark"));
       
   983 	TBufferMarkInfo* pTBufferMarkInfo = new TBufferMarkInfo(apMark);
       
   984 	if (!pTBufferMarkInfo)
       
   985 		{
       
   986 		return OMX_ErrorInsufficientResources;
       
   987 		}
       
   988 
       
   989 	iBufferMarks.AddLast(*pTBufferMarkInfo);
       
   990 
       
   991 	return OMX_ErrorNone;
       
   992 
       
   993 	}
       
   994 
       
   995 /**
       
   996    This utility method may be called from the most derived port
       
   997    class' destructor to delete any buffer header and or buffer that may remain
       
   998    allocated in the port. This typically happens when the component is unloaded
       
   999    without being properly transitioned from OMX_StateIdle to OMX_StateLoaded.
       
  1000 
       
  1001  */
       
  1002 void
       
  1003 COmxILPortImpl::CleanUpPort()
       
  1004 	{
       
  1005 
       
  1006 	// Do the clean-up here in case something went wrong and the component is
       
  1007 	// being unloaded in a failure scenario...
       
  1008 	const TInt headerCount = iBufferHeaders.Count();
       
  1009 	if (headerCount > 0)
       
  1010 		{
       
  1011 		if (!IsTunnelled())
       
  1012 			{
       
  1013 			// A non-tunnelled port needs to delete always the header and needs
       
  1014 			// to deallocate/unwrap the buffer depending on whether the buffer
       
  1015 			// is owned or not...
       
  1016 
       
  1017 			RPointerArray<OMX_BUFFERHEADERTYPE> tempHeadersArray;
       
  1018 			for (TInt i=0; i<headerCount; ++i)
       
  1019 				{
       
  1020 				tempHeadersArray.Append(iBufferHeaders[i].GetHeader());
       
  1021 				}
       
  1022 
       
  1023 			TBool portDepopulationCompleted = EFalse;
       
  1024 			for (TInt i=0; i<headerCount; ++i)
       
  1025 				{
       
  1026 				// Errors are ignored here ...
       
  1027 				FreeBuffer(tempHeadersArray[i], portDepopulationCompleted);
       
  1028 				}
       
  1029 			tempHeadersArray.Close();
       
  1030 
       
  1031 			}
       
  1032 		else
       
  1033 			{
       
  1034 			if (IsTunnelledAndBufferSupplier())
       
  1035 				{
       
  1036 				// A tunnelled supplier only needs to delete the buffers, not
       
  1037 				// the buffer headers... Also, we cannot use the pointer to the
       
  1038 				// buffer header, as it may not exist anymore...
       
  1039 				for (TInt i=0; i<headerCount; ++i)
       
  1040 					{
       
  1041 					iOmxILPort.DoBufferDeallocation(
       
  1042 						iBufferHeaders[i].GetBufferPointer(),
       
  1043 						iBufferHeaders[i].GetPortPointer(),
       
  1044 						iBufferHeaders[i].GetPlatformPointer(),
       
  1045 						iBufferHeaders[i].GetAppPointer());
       
  1046 					}
       
  1047 
       
  1048 				}
       
  1049 			else
       
  1050 				{
       
  1051 				// A tunnelled non-supplier needs to remove buffer headers and
       
  1052 				// undo the buffer wrapping, if any. We can use FreeBuffer for
       
  1053 				// that purpose...
       
  1054 				RPointerArray<OMX_BUFFERHEADERTYPE> tempHeadersArray;
       
  1055 				for (TInt i=0; i<headerCount; ++i)
       
  1056 					{
       
  1057 					tempHeadersArray.Append(iBufferHeaders[i].GetHeader());
       
  1058 					}
       
  1059 
       
  1060 				TBool portDepopulationCompleted = EFalse;
       
  1061 				for (TInt i=0; i<headerCount; ++i)
       
  1062 					{
       
  1063 					//  errors here...
       
  1064 					FreeBuffer(tempHeadersArray[i], portDepopulationCompleted);
       
  1065 					}
       
  1066 				tempHeadersArray.Close();
       
  1067 				}
       
  1068 			}
       
  1069 		}
       
  1070 
       
  1071 	}
       
  1072 
       
  1073 
       
  1074 OMX_ERRORTYPE
       
  1075 COmxILPortImpl::StoreBufferMark(OMX_HANDLETYPE& ipMarkTargetComponent,
       
  1076 							OMX_PTR& ipMarkData)
       
  1077 	{
       
  1078     DEBUG_PRINTF(_L8("COmxILPortImpl::StoreBufferMark"));
       
  1079 
       
  1080 	TBufferMarkInfo* pTBufferMarkInfo =
       
  1081 		new TBufferMarkInfo(ipMarkTargetComponent,
       
  1082 							ipMarkData, EFalse);
       
  1083 	if (!pTBufferMarkInfo)
       
  1084 		{
       
  1085 		return OMX_ErrorInsufficientResources;
       
  1086 		}
       
  1087 
       
  1088 	iBufferMarks.AddLast(*pTBufferMarkInfo);
       
  1089 
       
  1090 	return OMX_ErrorNone;
       
  1091 
       
  1092 	}
       
  1093 
       
  1094 TBool
       
  1095 COmxILPortImpl::HasAllBuffersAtHome() const
       
  1096 	{
       
  1097 
       
  1098 	__ASSERT_ALWAYS(IsTunnelledAndBufferSupplier(),
       
  1099 					User::Panic(KOmxILPortPanicCategory, 1));
       
  1100 
       
  1101 	const TInt headerCount = iBufferHeaders.Count();
       
  1102 	for (TInt i=0; i<headerCount; ++i)
       
  1103 		{
       
  1104 		if (!iBufferHeaders[i].IsBufferAtHome())
       
  1105 			{
       
  1106 			DEBUG_PRINTF(_L8("COmxILPortImpl::HasAllBuffersAtHome : [NO]"));
       
  1107 			return EFalse;
       
  1108 			}
       
  1109 		}
       
  1110 
       
  1111 	DEBUG_PRINTF(_L8("COmxILPortImpl::HasAllBuffersAtHome : [YES]"));
       
  1112 	return ETrue;
       
  1113 
       
  1114 	}
       
  1115 
       
  1116 TBool
       
  1117 COmxILPortImpl::IsBufferAtHome(OMX_BUFFERHEADERTYPE* apBufferHeader) const
       
  1118 	{
       
  1119 	DEBUG_PRINTF2(_L8("COmxILPortImpl::IsBufferAtHome : [%X]"), apBufferHeader);
       
  1120 
       
  1121 	TInt headerIndex = 0;
       
  1122 	if (KErrNotFound ==
       
  1123 		(headerIndex =
       
  1124 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
  1125 							 TIdentityRelation<TBufferInfo>(
       
  1126 								 &TBufferInfo::Compare))))
       
  1127 		{
       
  1128 		User::Panic(KOmxILPortPanicCategory, 1);
       
  1129 		}
       
  1130 
       
  1131 	DEBUG_PRINTF2(_L8("COmxILPortImpl::IsBufferAtHome : [%s]"), iBufferHeaders[headerIndex].IsBufferAtHome() ? "YES" : "NO");
       
  1132 
       
  1133 	return iBufferHeaders[headerIndex].IsBufferAtHome();
       
  1134 
       
  1135 	}
       
  1136 
       
  1137 TBool
       
  1138 COmxILPortImpl::TBufferInfo::Compare(const TBufferInfo& aBi1,
       
  1139 								 const TBufferInfo& aBi2)
       
  1140 	{
       
  1141 	return (aBi1.GetHeader() == aBi2.GetHeader() ? ETrue : EFalse);
       
  1142 	}