omxil/omxilcomponentcommon/src/common/omxilport.cpp
changeset 56 b6488ac24ddc
parent 47 481b3bce574a
child 57 1cbb0d5bf7f2
equal deleted inserted replaced
47:481b3bce574a 56:b6488ac24ddc
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 /**
       
    18  @file
       
    19  @internalComponent
       
    20 */
       
    21 
       
    22 #include <mmf/server/mmfbuffer.h>
       
    23 #include <mmf/server/mmfdatabuffer.h>
       
    24 
       
    25 #include "log.h"
       
    26 #include "omxilport.h"
       
    27 #include "omxilutil.h"
       
    28 
       
    29 
       
    30 const TInt COmxILPort::KMaxBufferMarksQueueSize;
       
    31 const TInt COmxILPort::KBufferMarkPropagationPortNotNeeded;
       
    32 
       
    33 
       
    34 EXPORT_C
       
    35 TOmxILCommonPortData::TOmxILCommonPortData(
       
    36 	OMX_VERSIONTYPE aOmxVersion,
       
    37 	OMX_U32 aPortIndex,
       
    38 	OMX_DIRTYPE aDirection,
       
    39 	OMX_U32 aBufferCountMin,
       
    40 	OMX_U32 aBufferSizeMin,
       
    41 	OMX_PORTDOMAINTYPE aPortDomain,
       
    42 	OMX_BOOL aBuffersContiguous,
       
    43 	OMX_U32 aBufferAlignment,
       
    44 	OMX_BUFFERSUPPLIERTYPE aBufferSupplier,
       
    45 	OMX_U32 aBufferMarkPropagationPortIndex)
       
    46 	:
       
    47 	iOmxVersion(aOmxVersion),
       
    48 	iPortIndex(aPortIndex),
       
    49 	iDirection(aDirection),
       
    50 	iBufferCountMin(aBufferCountMin),
       
    51 	iBufferSizeMin(aBufferSizeMin),
       
    52 	iPortDomain(aPortDomain),
       
    53 	iBuffersContiguous(aBuffersContiguous),
       
    54 	iBufferAlignment(aBufferAlignment),
       
    55 	iBufferSupplier(aBufferSupplier),
       
    56 	iBufferMarkPropagationPortIndex(aBufferMarkPropagationPortIndex)
       
    57 	{
       
    58 	}
       
    59 
       
    60 
       
    61 EXPORT_C
       
    62 COmxILPort::COmxILPort(const TOmxILCommonPortData& aCommonPortData)
       
    63 	:
       
    64 	iTunnelledComponent(0),
       
    65 	iTunnelledPort(0),
       
    66 	iBufferHeaders(),
       
    67 	iBufferMarks(_FOFF(TBufferMarkInfo, iLink)),
       
    68 	iTransitionState(EPortNotTransitioning),
       
    69 	iBufferMarkPropagationPortIndex(
       
    70 		aCommonPortData.iBufferMarkPropagationPortIndex)
       
    71 	{
       
    72     DEBUG_PRINTF(_L8("COmxILPort::COmxILPort"));
       
    73 
       
    74 	__ASSERT_DEBUG(aCommonPortData.iDirection == OMX_DirInput ||
       
    75 				   aCommonPortData.iDirection == OMX_DirOutput,
       
    76 				   User::Panic(KOmxILPortPanicCategory, 1));
       
    77 
       
    78 	// From Section 3.1.2.12.1 .
       
    79 	//
       
    80 	// nBufferCountMin : "The component shall define this non-zero default
       
    81 	// value."
       
    82 	//
       
    83 	// nBufferCountActual : "The component shall set a default value no less
       
    84 	// than nBufferCountMin for this field"
       
    85 	__ASSERT_DEBUG(aCommonPortData.iBufferCountMin > 0,
       
    86 				   User::Panic(KOmxILPortPanicCategory, 1));
       
    87 
       
    88 	// Filll in OMX_PARAM_PORTDEFINITIONTYPE
       
    89 	iParamPortDefinition.nSize				= sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
       
    90 	iParamPortDefinition.nVersion			= aCommonPortData.iOmxVersion;
       
    91 	iParamPortDefinition.nPortIndex			= aCommonPortData.iPortIndex;
       
    92 	iParamPortDefinition.eDir				= aCommonPortData.iDirection;
       
    93 	iParamPortDefinition.nBufferCountActual = aCommonPortData.iBufferCountMin;
       
    94 	iParamPortDefinition.nBufferCountMin	= aCommonPortData.iBufferCountMin;
       
    95 	iParamPortDefinition.nBufferSize		= aCommonPortData.iBufferSizeMin;
       
    96 	iParamPortDefinition.bEnabled			= OMX_TRUE;
       
    97 	iParamPortDefinition.bPopulated			= OMX_FALSE;
       
    98 	iParamPortDefinition.eDomain			= aCommonPortData.iPortDomain;
       
    99 	// NOTE: iParamPortDefinition.format must be finished up by concrete ports
       
   100 	iParamPortDefinition.bBuffersContiguous = aCommonPortData.iBuffersContiguous;
       
   101 	iParamPortDefinition.nBufferAlignment	= aCommonPortData.iBufferAlignment;
       
   102 
       
   103 	// Fill in OMX_PARAM_BUFFERSUPPLIERTYPE
       
   104 	iParamCompBufferSupplier.nSize			 = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
       
   105 	iParamCompBufferSupplier.nVersion		 = aCommonPortData.iOmxVersion;
       
   106 	iParamCompBufferSupplier.nPortIndex		 = aCommonPortData.iPortIndex;
       
   107 	iParamCompBufferSupplier.eBufferSupplier = aCommonPortData.iBufferSupplier;
       
   108 
       
   109 	}
       
   110 
       
   111 EXPORT_C
       
   112 COmxILPort::~COmxILPort()
       
   113 	{
       
   114     DEBUG_PRINTF(_L8("COmxILPort::~COmxILPort"));
       
   115 
       
   116 #ifdef _DEBUG
       
   117 	const TInt headerCount = iBufferHeaders.Count();
       
   118 	if (headerCount > 0)
       
   119 		{
       
   120 		DEBUG_PRINTF(_L8("COmxILPort::~COmxILPort :: ------------------------------- WARNING ---------------------------------------  "));
       
   121 		DEBUG_PRINTF2(_L8("COmxILPort::~COmxILPort :: [%d] Buffer headers still exist"), headerCount);
       
   122 		DEBUG_PRINTF(_L8("COmxILPort::~COmxILPort :: CleanUpPort() may be used from the most derived port class to delete them"));
       
   123 		DEBUG_PRINTF(_L8("COmxILPort::~COmxILPort :: ------------------------------- WARNING ---------------------------------------  "));
       
   124 		}
       
   125 #endif
       
   126 
       
   127 	iBufferHeaders.Close();
       
   128 	iBufferMarks.ResetAndDestroy();
       
   129 
       
   130 	}
       
   131 
       
   132 EXPORT_C OMX_ERRORTYPE
       
   133 COmxILPort::GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const
       
   134 	{
       
   135     DEBUG_PRINTF(_L8("COmxILPort::GetLocalOmxParamIndexes"));
       
   136 
       
   137 	TInt err = aIndexArray.InsertInOrder(OMX_IndexParamPortDefinition);
       
   138 
       
   139 	// Note that index duplication is OK.
       
   140 	if (KErrNone == err || KErrAlreadyExists == err)
       
   141 		{
       
   142 		err = aIndexArray.InsertInOrder(OMX_IndexParamCompBufferSupplier);
       
   143 		}
       
   144 
       
   145 	if (KErrNone != err && KErrAlreadyExists != err)
       
   146 		{
       
   147 		return OMX_ErrorInsufficientResources;
       
   148 		}
       
   149 
       
   150 	return OMX_ErrorNone;
       
   151 
       
   152 	}
       
   153 
       
   154 EXPORT_C OMX_ERRORTYPE
       
   155 COmxILPort::GetLocalOmxConfigIndexes(RArray<TUint>& /*aIndexArray*/) const
       
   156 	{
       
   157     DEBUG_PRINTF(_L8("COmxILPort::GetLocalOmxConfigIndexes"));
       
   158 
       
   159 	return OMX_ErrorNone;
       
   160 
       
   161 	}
       
   162 
       
   163 
       
   164 EXPORT_C OMX_ERRORTYPE
       
   165 COmxILPort::GetParameter(OMX_INDEXTYPE aParamIndex,
       
   166 						 TAny* apComponentParameterStructure) const
       
   167 	{
       
   168     DEBUG_PRINTF(_L8("COmxILPort::GetParameter"));
       
   169 
       
   170 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   171 	switch(aParamIndex)
       
   172 		{
       
   173 	case OMX_IndexParamPortDefinition:
       
   174 		{
       
   175 		if (OMX_ErrorNone != (omxRetValue =
       
   176 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   177 								  apComponentParameterStructure,
       
   178 								  sizeof(OMX_PARAM_PORTDEFINITIONTYPE))))
       
   179 			{
       
   180 			return omxRetValue;
       
   181 			}
       
   182 
       
   183 		OMX_PARAM_PORTDEFINITIONTYPE* pPortDefinition
       
   184 			= static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(
       
   185 				apComponentParameterStructure);
       
   186 
       
   187 		*pPortDefinition = iParamPortDefinition;
       
   188 		}
       
   189 		break;
       
   190 
       
   191 	case OMX_IndexParamCompBufferSupplier:
       
   192 		{
       
   193 		if (OMX_ErrorNone != (omxRetValue =
       
   194 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   195 								  apComponentParameterStructure,
       
   196 								  sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE))))
       
   197 			{
       
   198 			return omxRetValue;
       
   199 			}
       
   200 
       
   201 		OMX_PARAM_BUFFERSUPPLIERTYPE* pBufferSupplier
       
   202 			= static_cast<OMX_PARAM_BUFFERSUPPLIERTYPE*>(
       
   203 				apComponentParameterStructure);
       
   204 
       
   205 		pBufferSupplier->eBufferSupplier =
       
   206 			iParamCompBufferSupplier.eBufferSupplier;
       
   207 		}
       
   208 		break;
       
   209 
       
   210 	default:
       
   211 		{
       
   212 		return OMX_ErrorUnsupportedIndex;
       
   213 		}
       
   214 		};
       
   215 
       
   216 	return OMX_ErrorNone;
       
   217 
       
   218 	}
       
   219 
       
   220 EXPORT_C OMX_ERRORTYPE
       
   221 COmxILPort::SetParameter(OMX_INDEXTYPE aParamIndex,
       
   222 						 const TAny* apComponentParameterStructure,
       
   223 						 TBool& aUpdateProcessingFunction)
       
   224 	{
       
   225     DEBUG_PRINTF(_L8("COmxILPort::SetParameter"));
       
   226 
       
   227 	aUpdateProcessingFunction = EFalse;
       
   228 
       
   229 	OMX_ERRORTYPE omxRetValue = OMX_ErrorNone;
       
   230 	switch(aParamIndex)
       
   231 		{
       
   232 	case OMX_IndexParamPortDefinition:
       
   233 		{
       
   234 		if (OMX_ErrorNone != (omxRetValue =
       
   235 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   236 								  const_cast<OMX_PTR>(apComponentParameterStructure),
       
   237 								  sizeof(OMX_PARAM_PORTDEFINITIONTYPE))))
       
   238 			{
       
   239 			return omxRetValue;
       
   240 			}
       
   241 
       
   242 		const OMX_PARAM_PORTDEFINITIONTYPE* pPortDefinition
       
   243 			= static_cast<const OMX_PARAM_PORTDEFINITIONTYPE*>(
       
   244 				apComponentParameterStructure);
       
   245 
       
   246 		// Port Format must be set by the concrete port...
       
   247 		if (OMX_ErrorNone !=
       
   248 			(omxRetValue =
       
   249 			 SetFormatInPortDefinition(*pPortDefinition,
       
   250 									   aUpdateProcessingFunction)))
       
   251 			{
       
   252 			return omxRetValue;
       
   253 			}
       
   254 
       
   255 		// Set here only the additional read-write parameters of
       
   256 		// OMX_PARAM_PORTDEFINITIONTYPE
       
   257 		if (iParamPortDefinition.nBufferCountActual !=
       
   258 			pPortDefinition->nBufferCountActual)
       
   259 			{
       
   260 			if (pPortDefinition->nBufferCountActual <
       
   261 				iParamPortDefinition.nBufferCountMin)
       
   262 				{
       
   263 				return OMX_ErrorBadParameter;
       
   264 				}
       
   265 			iParamPortDefinition.nBufferCountActual =
       
   266 				pPortDefinition->nBufferCountActual;
       
   267 			aUpdateProcessingFunction = ETrue;
       
   268 			}
       
   269 
       
   270 		}
       
   271 		break;
       
   272 
       
   273 	case OMX_IndexParamCompBufferSupplier:
       
   274 		{
       
   275 		if (OMX_ErrorNone != (omxRetValue =
       
   276 							  TOmxILUtil::CheckOmxStructSizeAndVersion(
       
   277 								  const_cast<OMX_PTR>(apComponentParameterStructure),
       
   278 								  sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE))))
       
   279 			{
       
   280 			return omxRetValue;
       
   281 			}
       
   282 
       
   283 		const OMX_PARAM_BUFFERSUPPLIERTYPE* pBufferSupplier
       
   284 			= static_cast<const OMX_PARAM_BUFFERSUPPLIERTYPE*>(
       
   285 				apComponentParameterStructure);
       
   286 
       
   287 		// OMX_BufferSupplyOutput is the last of the supported values as of
       
   288 		// v1.1.1
       
   289 		if (iParamCompBufferSupplier.eBufferSupplier > OMX_BufferSupplyOutput)
       
   290 			{
       
   291 			return OMX_ErrorBadParameter;
       
   292 			}
       
   293 
       
   294 		if (iParamCompBufferSupplier.eBufferSupplier !=
       
   295 			pBufferSupplier->eBufferSupplier)
       
   296 			{
       
   297 			// The component providing the input port is responsible for
       
   298 			// signalling the tunnelled component about the buffer supplier
       
   299 			// override...
       
   300 			if (iTunnelledComponent &&
       
   301 				iParamPortDefinition.eDir == OMX_DirInput)
       
   302 				{
       
   303 				OMX_PARAM_BUFFERSUPPLIERTYPE bufferSupplierType;
       
   304 				bufferSupplierType.nSize		   = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
       
   305 				bufferSupplierType.nVersion		   = iParamPortDefinition.nVersion;
       
   306 				bufferSupplierType.nPortIndex	   = iTunnelledPort;
       
   307 				bufferSupplierType.eBufferSupplier = pBufferSupplier->eBufferSupplier;
       
   308 				OMX_ERRORTYPE retValue = OMX_ErrorUndefined;
       
   309 				if (OMX_ErrorNone !=
       
   310 					(retValue =
       
   311 					 OMX_SetParameter(iTunnelledComponent,
       
   312 									  OMX_IndexParamCompBufferSupplier,
       
   313 									  &bufferSupplierType)) )
       
   314 					{
       
   315 					return retValue;
       
   316 					}
       
   317 				}
       
   318 			iParamCompBufferSupplier.eBufferSupplier =
       
   319 				pBufferSupplier->eBufferSupplier;
       
   320 			}
       
   321 
       
   322 		}
       
   323 		break;
       
   324 	default:
       
   325 		{
       
   326 		return OMX_ErrorUnsupportedIndex;
       
   327 		}
       
   328 		};
       
   329 
       
   330 	return OMX_ErrorNone;
       
   331 
       
   332 	}
       
   333 
       
   334 
       
   335 EXPORT_C OMX_ERRORTYPE
       
   336 COmxILPort::GetConfig(OMX_INDEXTYPE /*aConfigIndex*/,
       
   337 					  TAny* /*apComponentConfigStructure*/) const
       
   338 	{
       
   339     DEBUG_PRINTF(_L8("COmxILPort::GetConfig"));
       
   340 	return OMX_ErrorUnsupportedIndex;
       
   341 	}
       
   342 
       
   343 EXPORT_C OMX_ERRORTYPE
       
   344 COmxILPort::SetConfig(OMX_INDEXTYPE /*aConfigIndex*/,
       
   345 					  const TAny* /*apComponentConfigStructure*/,
       
   346 					  TBool& /*aUpdateProcessingFunction*/)
       
   347 	{
       
   348     DEBUG_PRINTF(_L8("COmxILPort::SetConfig"));
       
   349 	return OMX_ErrorUnsupportedIndex;
       
   350 	}
       
   351 
       
   352 EXPORT_C OMX_ERRORTYPE
       
   353 COmxILPort::GetExtensionIndex(OMX_STRING /* aParameterName */,
       
   354 							  OMX_INDEXTYPE* /* apIndexType */) const
       
   355 	{
       
   356 	// This method is intended to be overridden by the concrete ports when
       
   357 	// needed...
       
   358 	return OMX_ErrorUnsupportedIndex;
       
   359 	}
       
   360 
       
   361 EXPORT_C OMX_ERRORTYPE
       
   362 COmxILPort::PopulateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr,
       
   363 						   const OMX_PTR apAppPrivate,
       
   364 						   OMX_U32 aSizeBytes,
       
   365 						   OMX_U8* apBuffer,
       
   366 						   TBool& portPopulationCompleted)
       
   367 	{
       
   368     DEBUG_PRINTF(_L8("COmxILPort::PopulateBuffer"));
       
   369 
       
   370 	portPopulationCompleted = EFalse;
       
   371 
       
   372 	if(aSizeBytes < iParamPortDefinition.nBufferSize)
       
   373 		{
       
   374 		return OMX_ErrorBadParameter;
       
   375 		}
       
   376 
       
   377 	// Allocate the buffer header...
       
   378 	OMX_BUFFERHEADERTYPE* pHeader = new OMX_BUFFERHEADERTYPE;
       
   379 	*appBufferHdr = pHeader;
       
   380 	if (!pHeader)
       
   381 		{
       
   382 		return OMX_ErrorInsufficientResources;
       
   383 		}
       
   384 
       
   385 	// Here, lets discriminate between apBuffer == 0 (AllocateBuffer) and
       
   386 	// apBuffer != 0 (UseBuffer)
       
   387 	TUint8* pPortSpecificBuffer = 0;
       
   388 	OMX_PTR pPortPrivate = 0;
       
   389 	OMX_PTR pPlatformPrivate = 0;
       
   390 	OMX_ERRORTYPE portSpecificErr = OMX_ErrorNone;
       
   391 	if (apBuffer)
       
   392 		{
       
   393 		//... (UseBuffer) Do any port-specific wrapping of the received buffer,
       
   394 		// if needed by the port....
       
   395 		portSpecificErr = DoBufferWrapping(aSizeBytes,
       
   396 										   apBuffer,
       
   397 										   pPortPrivate,
       
   398 										   pPlatformPrivate,
       
   399 										   apAppPrivate);
       
   400 		}
       
   401 	else
       
   402 		{
       
   403 		// ... (AllocateBuffer) Do the port-specific buffer allocation ...
       
   404 		portSpecificErr = DoBufferAllocation(aSizeBytes,
       
   405 											 pPortSpecificBuffer,
       
   406 											 pPortPrivate,
       
   407 											 pPlatformPrivate,
       
   408 											 apAppPrivate);
       
   409 		}
       
   410 
       
   411 	if (OMX_ErrorNone != portSpecificErr)
       
   412 		{
       
   413 		delete *appBufferHdr; *appBufferHdr = 0;
       
   414 		return portSpecificErr;
       
   415 		}
       
   416 
       
   417 
       
   418 	// Add to local list of buffer headers...
       
   419 	if (KErrNone !=
       
   420 		iBufferHeaders.Append(
       
   421 			TBufferInfo(pHeader,
       
   422 						(apBuffer ?
       
   423 						 TBufferInfo::EBufferAway :
       
   424 						 TBufferInfo::EBufferAtHome),
       
   425 						(apBuffer ?
       
   426 						 TBufferInfo::EBufferNotOwned :
       
   427 						 TBufferInfo::EBufferOwned),
       
   428 						apBuffer,
       
   429 						apAppPrivate,
       
   430 						pPlatformPrivate,
       
   431 						pPortPrivate)))
       
   432 		{
       
   433 		// Undo custom buffer allocation/wrapping
       
   434 		if (apBuffer)
       
   435 			{
       
   436 			DoBufferUnwrapping(
       
   437 				apBuffer,
       
   438 				pPortPrivate,
       
   439 				pPlatformPrivate,
       
   440 				apAppPrivate);
       
   441 
       
   442 			}
       
   443 		else
       
   444 			{
       
   445 			DoBufferDeallocation(
       
   446 				pPortSpecificBuffer,
       
   447 				pPortPrivate,
       
   448 				pPlatformPrivate,
       
   449 				apAppPrivate);
       
   450 			}
       
   451 		delete *appBufferHdr; *appBufferHdr = NULL;
       
   452 		return OMX_ErrorInsufficientResources;
       
   453 		}
       
   454 
       
   455 
       
   456 	// Fill in the header...
       
   457 	pHeader->nSize				  = sizeof(OMX_BUFFERHEADERTYPE);
       
   458 	pHeader->nVersion			  = iParamPortDefinition.nVersion;
       
   459 	pHeader->pBuffer			  = apBuffer ? apBuffer : pPortSpecificBuffer;
       
   460 	pHeader->nAllocLen			  = aSizeBytes;
       
   461 	pHeader->nFilledLen			  = 0;
       
   462 	pHeader->nOffset			  = 0;
       
   463 	pHeader->pAppPrivate		  = apAppPrivate;
       
   464 	pHeader->pPlatformPrivate	  = pPlatformPrivate;
       
   465 	pHeader->hMarkTargetComponent = 0;
       
   466 	pHeader->pMarkData			  = 0;
       
   467 	pHeader->nTickCount			  = 0;
       
   468 	pHeader->nTimeStamp			  = 0;
       
   469 	pHeader->nFlags				  = 0;
       
   470 
       
   471 
       
   472 	if (OMX_DirInput == iParamPortDefinition.eDir)
       
   473 		{
       
   474 		pHeader->pInputPortPrivate	= pPortPrivate;
       
   475 		pHeader->pOutputPortPrivate = 0;
       
   476 		pHeader->nInputPortIndex	= iParamPortDefinition.nPortIndex;
       
   477 		pHeader->nOutputPortIndex	= 0;
       
   478 		}
       
   479 	else
       
   480 		{
       
   481 		pHeader->pInputPortPrivate	= 0;
       
   482 		pHeader->pOutputPortPrivate = pPortPrivate;
       
   483 		pHeader->nInputPortIndex	= 0;
       
   484 		pHeader->nOutputPortIndex	= iParamPortDefinition.nPortIndex;
       
   485 		}
       
   486 
       
   487 	if (iParamPortDefinition.nBufferCountActual == iBufferHeaders.Count())
       
   488 		{
       
   489 		iParamPortDefinition.bPopulated = OMX_TRUE;
       
   490 		portPopulationCompleted			= ETrue;
       
   491 		}
       
   492 
       
   493 	return OMX_ErrorNone;
       
   494 
       
   495 	}
       
   496 
       
   497 
       
   498 EXPORT_C OMX_ERRORTYPE
       
   499 COmxILPort::FreeBuffer(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   500 					   TBool& portDepopulationCompleted)
       
   501 	{
       
   502     DEBUG_PRINTF2(_L8("COmxILPort::FreeBuffer : BUFFER [%X]"), apBufferHeader);
       
   503 
       
   504 	portDepopulationCompleted = EFalse;
       
   505 
       
   506 	TInt headerIndex = 0;
       
   507 	if (KErrNotFound ==
       
   508 		(headerIndex =
       
   509 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
   510 							 TIdentityRelation<TBufferInfo>(
       
   511 								 &TBufferInfo::Compare))))
       
   512 		{
       
   513 		return OMX_ErrorBadParameter;
       
   514 		}
       
   515 
       
   516 
       
   517 	OMX_PTR pPortPrivate =
       
   518 		OMX_DirInput == iParamPortDefinition.eDir ?
       
   519 		apBufferHeader->pInputPortPrivate :
       
   520 		apBufferHeader->pOutputPortPrivate;
       
   521 
       
   522 	if (iBufferHeaders[headerIndex].IsBufferOwned())
       
   523 		{
       
   524 		DoBufferDeallocation(
       
   525 			apBufferHeader->pBuffer,
       
   526 			pPortPrivate,
       
   527 			apBufferHeader->pPlatformPrivate,
       
   528 			apBufferHeader->pAppPrivate);
       
   529 		}
       
   530 	else
       
   531 		{
       
   532 		DoBufferUnwrapping(
       
   533 			apBufferHeader->pBuffer,
       
   534 			pPortPrivate,
       
   535 			apBufferHeader->pPlatformPrivate,
       
   536 			apBufferHeader->pAppPrivate);
       
   537 		}
       
   538 
       
   539 	delete apBufferHeader;
       
   540 	iBufferHeaders.Remove(headerIndex);
       
   541 
       
   542 	if (iBufferHeaders.Count() < iParamPortDefinition.nBufferCountActual)
       
   543 		{
       
   544 		iParamPortDefinition.bPopulated = OMX_FALSE;
       
   545 		}
       
   546 
       
   547 	if (0 == iBufferHeaders.Count())
       
   548 		{
       
   549 		portDepopulationCompleted = ETrue;
       
   550 		}
       
   551 
       
   552 	return OMX_ErrorNone;
       
   553 
       
   554 	}
       
   555 
       
   556 
       
   557 EXPORT_C OMX_ERRORTYPE
       
   558 COmxILPort::TunnelRequest(OMX_HANDLETYPE aTunneledComp,
       
   559 						  OMX_U32 aTunneledPort,
       
   560 						  OMX_TUNNELSETUPTYPE* apTunnelSetup)
       
   561 	{
       
   562     DEBUG_PRINTF(_L8("COmxILPort::TunnelRequest"));
       
   563 
       
   564 	// Check whether the tunnel is being torn down
       
   565 	if (!aTunneledComp)
       
   566 		{
       
   567 		// Cancel existing tunnel setup, if any
       
   568 		iTunnelledComponent = 0;
       
   569 		return OMX_ErrorNone;
       
   570 		}
       
   571 
       
   572 	// Check that we are receiving a valid tunnel setup structure
       
   573 	if (!apTunnelSetup)
       
   574 		{
       
   575 		return OMX_ErrorBadParameter;
       
   576 		}
       
   577 
       
   578 	// STEP 0: Retrieve the port definition from the tunnelled component...
       
   579 	OMX_PARAM_PORTDEFINITIONTYPE paramPortDef;
       
   580 	paramPortDef.nSize		= sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
       
   581 	paramPortDef.nVersion	= iParamPortDefinition.nVersion;
       
   582 	paramPortDef.nPortIndex = aTunneledPort;
       
   583 	if (OMX_ErrorNone !=
       
   584 		OMX_GetParameter(aTunneledComp,
       
   585 						 OMX_IndexParamPortDefinition,
       
   586 						 &paramPortDef) )
       
   587 		{
       
   588 		return OMX_ErrorUndefined;
       
   589 		}
       
   590 
       
   591 	if (OMX_DirOutput == iParamPortDefinition.eDir)
       
   592 		{
       
   593 		// OMX_DirOutput
       
   594 		//
       
   595 
       
   596 		// Step 1: Check that this output port is being tunnelled to an input
       
   597 		// port...
       
   598 		if (paramPortDef.eDir != OMX_DirInput)
       
   599 			{
       
   600 			return OMX_ErrorPortsNotCompatible;
       
   601 			}
       
   602 
       
   603 		// Step 2: Fill in the tunnel setup structure received...
       
   604 		apTunnelSetup->nTunnelFlags = 0;
       
   605 		apTunnelSetup->eSupplier	= iParamCompBufferSupplier.eBufferSupplier;
       
   606 
       
   607 		iTunnelledComponent	= aTunneledComp;
       
   608 		iTunnelledPort		= aTunneledPort;
       
   609 		}
       
   610 	else
       
   611 		{
       
   612 		// OMX_DirInput
       
   613 		//
       
   614 
       
   615 		// Check that this input port is being tunnelled to an output
       
   616 		// port...
       
   617 		if (paramPortDef.eDir != OMX_DirOutput)
       
   618 			{
       
   619 			return OMX_ErrorPortsNotCompatible;
       
   620 			}
       
   621 
       
   622 		// Check that there is something consistent in the tunnel setup data
       
   623 		// received...
       
   624 		if ((apTunnelSetup->eSupplier != OMX_BufferSupplyUnspecified) &&
       
   625 			(apTunnelSetup->eSupplier != OMX_BufferSupplyInput) &&
       
   626 			(apTunnelSetup->eSupplier != OMX_BufferSupplyOutput))
       
   627 			{
       
   628 			return OMX_ErrorBadParameter;
       
   629 			}
       
   630 
       
   631 		// Set tunnelled component and port as they will be needed by
       
   632 		// IsTunnelledPortCompatible...
       
   633 		iTunnelledComponent	= aTunneledComp;
       
   634 		iTunnelledPort		= aTunneledPort;
       
   635 
       
   636 		// Check domain-specific parameter compatibility (this is delegated
       
   637 		// to derived port classes)...
       
   638 		if (!IsTunnelledPortCompatible(paramPortDef))
       
   639 			{
       
   640 			iTunnelledComponent	= 0;
       
   641 			return OMX_ErrorPortsNotCompatible;
       
   642 			}
       
   643 
       
   644 		// Now, try to get to an understanding here...Work out which port will
       
   645 		// be buffer supplier...
       
   646 		OMX_BUFFERSUPPLIERTYPE bufferSupplierDecision =
       
   647 			OMX_BufferSupplyUnspecified;
       
   648 		if (apTunnelSetup->nTunnelFlags & OMX_PORTTUNNELFLAG_READONLY	||
       
   649 			( (apTunnelSetup->eSupplier == OMX_BufferSupplyInput) &&
       
   650 			  (iParamCompBufferSupplier.eBufferSupplier ==
       
   651 			   OMX_BufferSupplyInput ||
       
   652 			   iParamCompBufferSupplier.eBufferSupplier ==
       
   653 			   OMX_BufferSupplyUnspecified) ) ||
       
   654 			( (apTunnelSetup->eSupplier == OMX_BufferSupplyUnspecified) &&
       
   655 			  (iParamCompBufferSupplier.eBufferSupplier ==
       
   656 			   OMX_BufferSupplyInput)) )
       
   657 			{
       
   658 			bufferSupplierDecision = OMX_BufferSupplyInput;
       
   659 			}
       
   660 		else
       
   661 			{
       
   662 			bufferSupplierDecision = OMX_BufferSupplyOutput;
       
   663 			}
       
   664 
       
   665 		// Set buffer supplier param in tunnelled port...
       
   666 		OMX_PARAM_BUFFERSUPPLIERTYPE bufferSupplierType;
       
   667 		bufferSupplierType.nSize		   = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
       
   668 		bufferSupplierType.nVersion		   = iParamPortDefinition.nVersion;
       
   669 		bufferSupplierType.nPortIndex	   = aTunneledPort;
       
   670 		bufferSupplierType.eBufferSupplier = bufferSupplierDecision;
       
   671 		if (OMX_ErrorNone !=
       
   672 			OMX_SetParameter(aTunneledComp,
       
   673 							 OMX_IndexParamCompBufferSupplier,
       
   674 							 &bufferSupplierType) )
       
   675 			{
       
   676 			iTunnelledComponent = 0;
       
   677 			return OMX_ErrorPortsNotCompatible;
       
   678 			}
       
   679 
       
   680 		apTunnelSetup->eSupplier = bufferSupplierDecision;
       
   681 		iParamCompBufferSupplier.eBufferSupplier = bufferSupplierDecision;
       
   682 
       
   683 		}
       
   684 
       
   685 	return OMX_ErrorNone;
       
   686 
       
   687 	}
       
   688 
       
   689 
       
   690 EXPORT_C OMX_ERRORTYPE
       
   691 COmxILPort::PopulateTunnel(TBool& portPopulationCompleted)
       
   692 	{
       
   693     DEBUG_PRINTF(_L8("COmxILPort::PopulateTunnel"));
       
   694 
       
   695 	__ASSERT_DEBUG(iBufferHeaders.Count() == 0,
       
   696 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   697 	__ASSERT_DEBUG(IsTunnelledAndBufferSupplier(),
       
   698 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   699 
       
   700 	portPopulationCompleted = EFalse;
       
   701 
       
   702 	// STEP 1: Obtain the number of buffers that the tunnelled port requires to
       
   703 	// be populated...  Retrieve the port definition from the tunnelled
       
   704 	// component
       
   705 	OMX_PARAM_PORTDEFINITIONTYPE paramPortDef;
       
   706 	paramPortDef.nSize		= sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
       
   707 	paramPortDef.nVersion	= iParamPortDefinition.nVersion;
       
   708 	paramPortDef.nPortIndex = iTunnelledPort;
       
   709 	if (OMX_ErrorNone !=
       
   710 		OMX_GetParameter(iTunnelledComponent,
       
   711 						 OMX_IndexParamPortDefinition,
       
   712 						 &paramPortDef) )
       
   713 		{
       
   714 		return OMX_ErrorUndefined;
       
   715 		}
       
   716 
       
   717 	// Step 2: Both ports must have the same threshold value (number of buffers
       
   718 	// to be populated) before completing the transition to
       
   719 	// OMX_StateIdle...Otherwise the population process would complete earlier
       
   720 	// or never...
       
   721 	TUint numOfBuffersToPopulate = iParamPortDefinition.nBufferCountActual;
       
   722 	if(paramPortDef.nBufferCountActual !=
       
   723 	   iParamPortDefinition.nBufferCountActual)
       
   724 		{
       
   725 		numOfBuffersToPopulate =
       
   726 			Max(iParamPortDefinition.nBufferCountActual,
       
   727 				paramPortDef.nBufferCountActual);
       
   728 		if (iParamPortDefinition.nBufferCountActual <
       
   729 			numOfBuffersToPopulate)
       
   730 			{
       
   731 			// Update own buffer count requirements
       
   732 			DEBUG_PRINTF3(_L8("COmxILPort::PopulateTunnel : Updated own nBufferCountActual - Old Value [%d] New Value [%d] "),
       
   733 						  iParamPortDefinition.nBufferCountActual, numOfBuffersToPopulate);
       
   734 			iParamPortDefinition.nBufferCountActual = numOfBuffersToPopulate;
       
   735 			}
       
   736 		else
       
   737 			{
       
   738 			// Update peer's buffer count requirements
       
   739 			DEBUG_PRINTF3(_L8("COmxILPort::PopulateTunnel : Updated peer's nBufferCountActual - Old Value [%d] New Value [%d] "),
       
   740 						  paramPortDef.nBufferCountActual, numOfBuffersToPopulate);
       
   741 			paramPortDef.nBufferCountActual = numOfBuffersToPopulate;
       
   742 			if (OMX_ErrorNone != OMX_SetParameter(iTunnelledComponent,
       
   743 												  OMX_IndexParamPortDefinition,
       
   744 												  &paramPortDef))
       
   745 				{
       
   746 				DEBUG_PRINTF(_L8("COmxILPort::PopulateTunnel : Error setting nBufferCountActual in tunnelled component "));
       
   747 				return OMX_ErrorUndefined;
       
   748 				}
       
   749 			}
       
   750 		}
       
   751 
       
   752 	// STEP 3: Start population of the tunnel...
       
   753 	TUint sizeOfBuffersToPopulate =
       
   754 		iParamPortDefinition.nBufferSize >= paramPortDef.nBufferSize  ?
       
   755 		iParamPortDefinition.nBufferSize :
       
   756 		paramPortDef.nBufferSize;
       
   757 
       
   758 	OMX_BUFFERHEADERTYPE* pHeader = 0;
       
   759 	TUint8* pPortSpecificBuffer = 0;
       
   760 	OMX_PTR pPortPrivate = 0;
       
   761 	OMX_PTR pPlatformPrivate = 0;
       
   762 	OMX_ERRORTYPE portSpecificErr = OMX_ErrorNone;
       
   763 	for (TUint i=0; i<numOfBuffersToPopulate; i++)
       
   764 		{
       
   765 		// Allocate the buffer...
       
   766 		if (OMX_ErrorNone !=
       
   767 			(portSpecificErr = DoBufferAllocation(
       
   768 				sizeOfBuffersToPopulate,
       
   769 				pPortSpecificBuffer,
       
   770 				pPortPrivate,
       
   771 				pPlatformPrivate)))
       
   772 			{
       
   773 			// There's no point on continuing here... the tunnel will never
       
   774 			// be completely populated now...
       
   775 			return portSpecificErr;
       
   776 			}
       
   777 		
       
   778 		OMX_ERRORTYPE useBufRes = DoOmxUseBuffer(iTunnelledComponent,
       
   779 												 &pHeader,
       
   780 												 iTunnelledPort,
       
   781 												 pPortPrivate,
       
   782 												 pPlatformPrivate,
       
   783 												 sizeOfBuffersToPopulate,
       
   784 												 pPortSpecificBuffer);
       
   785 
       
   786 		if ((OMX_ErrorNone != useBufRes) || !pHeader)
       
   787 			{
       
   788 			DoBufferDeallocation(
       
   789 				pPortSpecificBuffer,
       
   790 				pPortPrivate,
       
   791 				pPlatformPrivate);
       
   792 
       
   793 			if (pHeader)
       
   794 				{
       
   795 				switch(useBufRes)
       
   796 					{
       
   797 				case OMX_ErrorIncorrectStateOperation:
       
   798 					{
       
   799 					// Here, the tunnelled component is not ready. Probably,
       
   800 					// the IL Client has not commanded yet the component to go
       
   801 					// to OMX_StateIdle. Out-of-context implementations could
       
   802 					// do here a backoff-and-retry procedure. This
       
   803 					// implementation can just return and expect that the IL
       
   804 					// Client will detect the situation of this component not
       
   805 					// transitioning to OMX_StateIdle.
       
   806 					DEBUG_PRINTF(_L8("COmxILPort::PopulateTunnel : OMX_ErrorIncorrectStateOperation received from non-supplier component"));
       
   807 					}
       
   808 					break;
       
   809 					};
       
   810 				}
       
   811 				
       
   812 			if (OMX_ErrorInsufficientResources == useBufRes)
       
   813 				{
       
   814 				return OMX_ErrorInsufficientResources; 
       
   815 				}
       
   816 			// This is a gotcha. Here there is some problem with the tunnelled
       
   817 			// component. If we return the received error, this component may
       
   818 			// be sending back some error code that is not allowed in
       
   819 			// OMX_SendCommand. Example: The component conformance suite
       
   820 			// expects here OMX_ErrorNone if the tunnelled component does not
       
   821 			// support OMX_UseBuffer or some other problem. Also, we don't send
       
   822 			// and error event here as there's no appropriate error for this
       
   823 			// situation (OMX_ErrorPortUnresponsiveDuringAllocation is for
       
   824 			// non-supplier ports). Therefore, the IL Client should recover
       
   825 			// from this situation after some time by detecting that this
       
   826 			// component didn't transition to OMX_StateIdle.
       
   827 					
       
   828 			return OMX_ErrorNone;
       
   829 			}
       
   830 		// Fill the data in the received header so we can correctly use it when
       
   831 		// the header is at this side of the tunnel...
       
   832 		if (OMX_DirInput == iParamPortDefinition.eDir)
       
   833 			{
       
   834 			pHeader->pInputPortPrivate = pPortPrivate;
       
   835 			pHeader->nInputPortIndex   = iParamPortDefinition.nPortIndex;
       
   836 			}
       
   837 		else	// OMX_DirOutput == iParamPortDefinition.eDir
       
   838 			{
       
   839 			pHeader->pOutputPortPrivate = pPortPrivate;
       
   840 			pHeader->nOutputPortIndex	= iParamPortDefinition.nPortIndex;
       
   841 			}
       
   842 
       
   843 		// Add to local list of buffer headers... return if not sucessful...
       
   844 		if (KErrNone !=
       
   845 			iBufferHeaders.Append(
       
   846 				TBufferInfo(pHeader,
       
   847 							TBufferInfo::EBufferAtHome,
       
   848 							TBufferInfo::EBufferOwned,
       
   849 							pPortSpecificBuffer,
       
   850 							0,
       
   851 							pPlatformPrivate,
       
   852 							pPortPrivate)))
       
   853 			{
       
   854 			DoBufferDeallocation(
       
   855 				pPortSpecificBuffer,
       
   856 				pPortPrivate,
       
   857 				pPlatformPrivate);
       
   858 
       
   859 			return OMX_ErrorInsufficientResources;
       
   860 			}
       
   861 		}
       
   862 
       
   863 	iParamPortDefinition.bPopulated = OMX_TRUE;
       
   864 	portPopulationCompleted			= ETrue;
       
   865 
       
   866 	__ASSERT_DEBUG(iBufferHeaders.Count()	  ==
       
   867 				   iParamPortDefinition.nBufferCountActual,
       
   868 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   869 
       
   870 	return OMX_ErrorNone;
       
   871 
       
   872 	}
       
   873 
       
   874 
       
   875 EXPORT_C OMX_ERRORTYPE
       
   876 COmxILPort::FreeTunnel(TBool& portDepopulationCompleted)
       
   877 	{
       
   878     DEBUG_PRINTF(_L8("COmxILPort::FreeTunnel"));
       
   879 
       
   880   	__ASSERT_DEBUG(iBufferHeaders.Count() ==
       
   881   				   iParamPortDefinition.nBufferCountActual,
       
   882   				   User::Panic(KOmxILPortPanicCategory, 1));	
       
   883 	
       
   884 	__ASSERT_DEBUG(IsTunnelledAndBufferSupplier(),
       
   885 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   886 
       
   887 	const TUint numBuffersToDepopulate = iBufferHeaders.Count();
       
   888 	for (TUint i=0; i<numBuffersToDepopulate; ++i)
       
   889 		{
       
   890 		OMX_BUFFERHEADERTYPE* pBufferHeader = iBufferHeaders[i].GetHeader();
       
   891 
       
   892 		// Take some things from the header, before it gets deleted by the
       
   893 		// tunnelled port...
       
   894 		OMX_U8* pBuffer = pBufferHeader->pBuffer;
       
   895 		OMX_PTR pPortPrivate =
       
   896 			OMX_DirInput == iParamPortDefinition.eDir ?
       
   897 			pBufferHeader->pInputPortPrivate :
       
   898 			pBufferHeader->pOutputPortPrivate;
       
   899 		OMX_PTR pAppPrivate = pBufferHeader->pAppPrivate;
       
   900 		OMX_PTR pPlatformPrivate = pBufferHeader->pPlatformPrivate;
       
   901 
       
   902 		DEBUG_PRINTF2(_L8("COmxILPort::FreeTunnel : BUFFER [%X]"), iBufferHeaders[i].GetHeader());
       
   903 
       
   904 		OMX_ERRORTYPE freeBufRes = OMX_FreeBuffer(
       
   905 			iTunnelledComponent,
       
   906 			iTunnelledPort,
       
   907 			pBufferHeader);
       
   908 
       
   909 		// At this point, the actual buffer header should no longer exist...
       
   910 		pBufferHeader = 0;
       
   911 
       
   912 		// NOTE that we don't check OMX_FreeBuffer returned error here. If
       
   913 		// something wrong happens at the tunnelled component side we'll
       
   914 		// continue here and try to free as many buffers as possible.... at
       
   915 		// least the state of this component will remain valid.... (we don't
       
   916 		// report errors coming from the tunnelled component as that is its
       
   917 		// responsibility....)
       
   918 
       
   919 		DoBufferDeallocation(
       
   920 			pBuffer,
       
   921 			pPortPrivate,
       
   922 			pPlatformPrivate,
       
   923 			pAppPrivate);
       
   924 		}
       
   925 
       
   926 	// Clear the local list of headers. Note that there's no need to delete the
       
   927 	// header as these have been allocated by the tunnelled port...
       
   928 
       
   929 	iBufferHeaders.Reset();
       
   930 	iParamPortDefinition.bPopulated = OMX_FALSE;
       
   931 	portDepopulationCompleted = ETrue;
       
   932 
       
   933 	__ASSERT_DEBUG(iBufferHeaders.Count() == 0,
       
   934 				   User::Panic(KOmxILPortPanicCategory, 1));
       
   935 
       
   936 	return OMX_ErrorNone;
       
   937 
       
   938 	}
       
   939 
       
   940 
       
   941 
       
   942 EXPORT_C TBool
       
   943 COmxILPort::SetBufferSent(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   944 						  TBool& aBufferMarkedWithOwnMark)
       
   945 	{
       
   946     DEBUG_PRINTF(_L8("COmxILPort::SetBufferSent"));
       
   947 
       
   948 	__ASSERT_DEBUG(apBufferHeader, User::Panic(KOmxILPortPanicCategory, 1));
       
   949 
       
   950 	aBufferMarkedWithOwnMark = EFalse;
       
   951 
       
   952 	TInt index = 0;
       
   953 	if (KErrNotFound ==
       
   954 		(index =
       
   955 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
   956 							 TIdentityRelation<TBufferInfo>(
       
   957 								 &TBufferInfo::Compare))))
       
   958 		{
       
   959 		return EFalse;
       
   960 		}
       
   961 
       
   962 	iBufferHeaders[index].SetBufferAway();
       
   963 
       
   964 	if (!iBufferMarks.IsEmpty())
       
   965 		{
       
   966 		// Check for existing marks in the buffer header...
       
   967 		if (apBufferHeader->hMarkTargetComponent)
       
   968 			{
       
   969 			// We queue the mark received within the buffer header if there are
       
   970 			// marks already to be delivered... it is mandatory to give a FIFO
       
   971 			// preference to the marks received by a port..
       
   972 			if (iBufferMarks.Elements() < KMaxBufferMarksQueueSize)
       
   973 				{
       
   974 				// The buffer is marked already. Store the current mark at the end
       
   975 				// of the buffer mark list...
       
   976 				StoreBufferMark(apBufferHeader->hMarkTargetComponent,
       
   977 								apBufferHeader->pMarkData);
       
   978 				}
       
   979 			}
       
   980 
       
   981 		// Use the first mark in the queue...
       
   982 		TBufferMarkInfo* pMark = iBufferMarks.First();
       
   983 		apBufferHeader->hMarkTargetComponent = pMark->ipMarkTargetComponent;
       
   984 		apBufferHeader->pMarkData			 = pMark->ipMarkData;
       
   985 		aBufferMarkedWithOwnMark			 = pMark->iOwnMark;
       
   986 		iBufferMarks.Remove(*pMark);
       
   987 		delete pMark;
       
   988 		}
       
   989 
       
   990 	return ETrue;
       
   991 
       
   992 	}
       
   993 
       
   994 EXPORT_C TBool
       
   995 COmxILPort::SetBufferReturned(OMX_BUFFERHEADERTYPE* apBufferHeader)
       
   996 	{
       
   997     DEBUG_PRINTF(_L8("COmxILPort::SetBufferReturned"));
       
   998 
       
   999 	__ASSERT_DEBUG(apBufferHeader, User::Panic(KOmxILPortPanicCategory, 1));
       
  1000 
       
  1001 	TInt index = 0;
       
  1002 	if (KErrNotFound ==
       
  1003 		(index =
       
  1004 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
  1005 							 TIdentityRelation<TBufferInfo>(
       
  1006 								 &TBufferInfo::Compare))))
       
  1007 		{
       
  1008 		return EFalse;
       
  1009 		}
       
  1010 
       
  1011 	iBufferHeaders[index].SetBufferAtHome();
       
  1012 
       
  1013 	return ETrue;
       
  1014 
       
  1015 	}
       
  1016 
       
  1017 EXPORT_C void
       
  1018 COmxILPort::SetTransitionToEnabled()
       
  1019 	{
       
  1020     DEBUG_PRINTF(_L8("COmxILPort::SetTransitionToEnabled"));
       
  1021 
       
  1022 	iTransitionState = EPortTransitioningToEnabled;
       
  1023 	iParamPortDefinition.bEnabled = OMX_TRUE;
       
  1024 
       
  1025 	}
       
  1026 
       
  1027 EXPORT_C void
       
  1028 COmxILPort::SetTransitionToDisabled()
       
  1029 	{
       
  1030     DEBUG_PRINTF(_L8("COmxILPort::SetTransitionToDisabled"));
       
  1031 
       
  1032 	iTransitionState = EPortTransitioningToDisabled;
       
  1033 	iParamPortDefinition.bEnabled = OMX_FALSE;
       
  1034 
       
  1035 	}
       
  1036 
       
  1037 EXPORT_C void
       
  1038 COmxILPort::SetTransitionToDisabledCompleted()
       
  1039 	{
       
  1040     DEBUG_PRINTF(_L8("COmxILPort::SetTransitionToDisabledCompleted"));
       
  1041 
       
  1042 	iTransitionState = EPortNotTransitioning;
       
  1043 	iParamPortDefinition.bEnabled = OMX_FALSE;
       
  1044 
       
  1045 	}
       
  1046 
       
  1047 EXPORT_C void
       
  1048 COmxILPort::SetTransitionToEnabledCompleted()
       
  1049 	{
       
  1050     DEBUG_PRINTF(_L8("COmxILPort::SetTransitionToEnabledCompleted"));
       
  1051 
       
  1052 	iTransitionState = EPortNotTransitioning;
       
  1053 	iParamPortDefinition.bEnabled = OMX_TRUE;
       
  1054 
       
  1055 	}
       
  1056 
       
  1057 EXPORT_C OMX_ERRORTYPE
       
  1058 COmxILPort::StoreBufferMark(const OMX_MARKTYPE* apMark)
       
  1059 	{
       
  1060     DEBUG_PRINTF(_L8("COmxILPort::StoreBufferMark"));
       
  1061 	TBufferMarkInfo* pTBufferMarkInfo = new TBufferMarkInfo(apMark);
       
  1062 	if (!pTBufferMarkInfo)
       
  1063 		{
       
  1064 		return OMX_ErrorInsufficientResources;
       
  1065 		}
       
  1066 
       
  1067 	iBufferMarks.AddLast(*pTBufferMarkInfo);
       
  1068 
       
  1069 	return OMX_ErrorNone;
       
  1070 
       
  1071 	}
       
  1072 
       
  1073 
       
  1074 /**
       
  1075    This utility method may be called from the most derived port
       
  1076    class' destructor to delete any buffer header and or buffer that may remain
       
  1077    allocated in the port. This typically happens when the component is unloaded
       
  1078    without being properly transitioned from OMX_StateIdle to OMX_StateLoaded.
       
  1079 
       
  1080  */
       
  1081 EXPORT_C void
       
  1082 COmxILPort::CleanUpPort()
       
  1083 	{
       
  1084 
       
  1085 	// Do the clean-up here in case something went wrong and the component is
       
  1086 	// being unloaded in a failure scenario...
       
  1087 	const TInt headerCount = iBufferHeaders.Count();
       
  1088 	if (headerCount > 0)
       
  1089 		{
       
  1090 		if (!IsTunnelled())
       
  1091 			{
       
  1092 			// A non-tunnelled port needs to delete always the header and needs
       
  1093 			// to deallocate/unwrap the buffer depending on whether the buffer
       
  1094 			// is owned or not...
       
  1095 
       
  1096 			RPointerArray<OMX_BUFFERHEADERTYPE> tempHeadersArray;
       
  1097 			for (TInt i=0; i<headerCount; ++i)
       
  1098 				{
       
  1099 				tempHeadersArray.Append(iBufferHeaders[i].GetHeader());
       
  1100 				}
       
  1101 
       
  1102 			TBool portDepopulationCompleted = EFalse;
       
  1103 			for (TInt i=0; i<headerCount; ++i)
       
  1104 				{
       
  1105 				// Errors are ignored here ...
       
  1106 				FreeBuffer(tempHeadersArray[i], portDepopulationCompleted);
       
  1107 				}
       
  1108 			tempHeadersArray.Close();
       
  1109 
       
  1110 			}
       
  1111 		else
       
  1112 			{
       
  1113 			if (IsTunnelledAndBufferSupplier())
       
  1114 				{
       
  1115 				// A tunnelled supplier only needs to delete the buffers, not
       
  1116 				// the buffer headers... Also, we cannot use the pointer to the
       
  1117 				// buffer header, as it may not exist anymore...
       
  1118 				for (TInt i=0; i<headerCount; ++i)
       
  1119 					{
       
  1120 					DoBufferDeallocation(
       
  1121 						iBufferHeaders[i].GetBufferPointer(),
       
  1122 						iBufferHeaders[i].GetPortPointer(),
       
  1123 						iBufferHeaders[i].GetPlatformPointer(),
       
  1124 						iBufferHeaders[i].GetAppPointer());
       
  1125 					}
       
  1126 
       
  1127 				}
       
  1128 			else
       
  1129 				{
       
  1130 				// A tunnelled non-supplier needs to remove buffer headers and
       
  1131 				// undo the buffer wrapping, if any. We can use FreeBuffer for
       
  1132 				// that purpose...
       
  1133 				RPointerArray<OMX_BUFFERHEADERTYPE> tempHeadersArray;
       
  1134 				for (TInt i=0; i<headerCount; ++i)
       
  1135 					{
       
  1136 					tempHeadersArray.Append(iBufferHeaders[i].GetHeader());
       
  1137 					}
       
  1138 
       
  1139 				TBool portDepopulationCompleted = EFalse;
       
  1140 				for (TInt i=0; i<headerCount; ++i)
       
  1141 					{
       
  1142 					//  errors here...
       
  1143 					FreeBuffer(tempHeadersArray[i], portDepopulationCompleted);
       
  1144 					}
       
  1145 				tempHeadersArray.Close();
       
  1146 				}
       
  1147 			}
       
  1148 		}
       
  1149 
       
  1150 	}
       
  1151 
       
  1152 /**
       
  1153    This is to be overriden by concrete ports that either support more than
       
  1154    one role or that want to let the IL Client to reset the component to
       
  1155    some default state...
       
  1156 
       
  1157    @param aComponentRoleIndex The index of the role that is to be assumed by
       
  1158    the component.
       
  1159 
       
  1160    @return OMX_ERRORTYPE
       
  1161  */
       
  1162 EXPORT_C OMX_ERRORTYPE
       
  1163 COmxILPort::SetComponentRoleDefaults(TUint /*aComponentRoleIndex*/)
       
  1164 	{
       
  1165     DEBUG_PRINTF(_L8("COmxILPort::SetComponentRoleDefaults"));
       
  1166 
       
  1167 	return OMX_ErrorNotImplemented;
       
  1168 	}
       
  1169 
       
  1170 /**
       
  1171    This is to be overriden by concrete ports that either support more than one
       
  1172    role or that want to let the IL Client to reset the component to some
       
  1173    default state...
       
  1174 
       
  1175    @param aPortSettingsIndex An implementation-specific identifier that the
       
  1176    implementation associates to the setting(s) that need(s) updating in the
       
  1177    port.
       
  1178 
       
  1179    @param aPortSettings A buffer descriptor that contains an
       
  1180    implementation-specific structure with the new setting(s) that need to
       
  1181    be updated in the port.
       
  1182 
       
  1183    @param [output] aEventForILClient An event that the port may choose to
       
  1184    deliver to the IL Client. This should be one of OMX_EventPortSettingsChanged
       
  1185    or OMX_EventPortFormatDetected. Use OMX_EventMax if no event need to be
       
  1186    sent.
       
  1187  */
       
  1188 EXPORT_C OMX_ERRORTYPE
       
  1189 COmxILPort::DoPortReconfiguration(TUint /* aPortSettingsIndex */,
       
  1190 								  const TDesC8& /* aPortSettings */,
       
  1191 								  OMX_EVENTTYPE& aEventForILClient)
       
  1192 	{
       
  1193     DEBUG_PRINTF(_L8("COmxILPort::DoPortReconfiguration"));
       
  1194 
       
  1195 	// This means no need to notify the IL Client...
       
  1196 	aEventForILClient = OMX_EventMax;
       
  1197 
       
  1198 	return OMX_ErrorNotImplemented;
       
  1199 	}
       
  1200 
       
  1201 EXPORT_C OMX_ERRORTYPE
       
  1202 COmxILPort::StoreBufferMark(OMX_HANDLETYPE& ipMarkTargetComponent,
       
  1203 							OMX_PTR& ipMarkData)
       
  1204 	{
       
  1205     DEBUG_PRINTF(_L8("COmxILPort::StoreBufferMark"));
       
  1206 
       
  1207 	TBufferMarkInfo* pTBufferMarkInfo =
       
  1208 		new TBufferMarkInfo(ipMarkTargetComponent,
       
  1209 							ipMarkData, EFalse);
       
  1210 	if (!pTBufferMarkInfo)
       
  1211 		{
       
  1212 		return OMX_ErrorInsufficientResources;
       
  1213 		}
       
  1214 
       
  1215 	iBufferMarks.AddLast(*pTBufferMarkInfo);
       
  1216 
       
  1217 	return OMX_ErrorNone;
       
  1218 
       
  1219 	}
       
  1220 
       
  1221 EXPORT_C TBool
       
  1222 COmxILPort::HasAllBuffersAtHome() const
       
  1223 	{
       
  1224 
       
  1225 	__ASSERT_ALWAYS(IsTunnelledAndBufferSupplier(),
       
  1226 					User::Panic(KOmxILPortPanicCategory, 1));
       
  1227 
       
  1228 	const TInt headerCount = iBufferHeaders.Count();
       
  1229 	for (TInt i=0; i<headerCount; ++i)
       
  1230 		{
       
  1231 		if (!iBufferHeaders[i].IsBufferAtHome())
       
  1232 			{
       
  1233 			DEBUG_PRINTF(_L8("COmxILPort::HasAllBuffersAtHome : [NO]"));
       
  1234 			return EFalse;
       
  1235 			}
       
  1236 		}
       
  1237 
       
  1238 	DEBUG_PRINTF(_L8("COmxILPort::HasAllBuffersAtHome : [YES]"));
       
  1239 	return ETrue;
       
  1240 
       
  1241 	}
       
  1242 
       
  1243 EXPORT_C TBool
       
  1244 COmxILPort::IsBufferAtHome(OMX_BUFFERHEADERTYPE* apBufferHeader) const
       
  1245 	{
       
  1246 	DEBUG_PRINTF2(_L8("COmxILPort::IsBufferAtHome : [%X]"), apBufferHeader);
       
  1247 
       
  1248 	TInt headerIndex = 0;
       
  1249 	if (KErrNotFound ==
       
  1250 		(headerIndex =
       
  1251 		 iBufferHeaders.Find(TBufferInfo(apBufferHeader),
       
  1252 							 TIdentityRelation<TBufferInfo>(
       
  1253 								 &TBufferInfo::Compare))))
       
  1254 		{
       
  1255 		User::Panic(KOmxILPortPanicCategory, 1);
       
  1256 		}
       
  1257 
       
  1258 	DEBUG_PRINTF2(_L8("COmxILPort::IsBufferAtHome : [%s]"), iBufferHeaders[headerIndex].IsBufferAtHome() ? "YES" : "NO");
       
  1259 
       
  1260 	return iBufferHeaders[headerIndex].IsBufferAtHome();
       
  1261 
       
  1262 	}
       
  1263 
       
  1264 
       
  1265 /**
       
  1266    This method provides a mechanism for ports to place the port-specific
       
  1267    buffer allocation logic (typically used in an OMX_AllocateBuffer
       
  1268    scenario).
       
  1269 
       
  1270    @param aSizeBytes The size in bytes of the buffer to be allocated.
       
  1271 
       
  1272    @param [OUT] apPortSpecificBuffer A pointer to the memory area allocated by
       
  1273    the port.
       
  1274 
       
  1275    @param [OUT] apPortPrivate A pointer that refers to an optional
       
  1276    port-specific structure.
       
  1277 
       
  1278    @param apPlatformPrivate[OUT] A pointer to an optional platform-specific
       
  1279    structure.
       
  1280 
       
  1281    @param apAppPrivate A pointer that refers to a buffer supplier-specific
       
  1282    structure.
       
  1283 
       
  1284    @return OMX_ERRORTYPE
       
  1285 */
       
  1286 EXPORT_C OMX_ERRORTYPE
       
  1287 COmxILPort::DoBufferAllocation(OMX_U32 aSizeBytes,
       
  1288 							   OMX_U8*& apPortSpecificBuffer,
       
  1289 							   OMX_PTR& apPortPrivate,
       
  1290 							   OMX_PTR& /* apPlatformPrivate */,
       
  1291 							   OMX_PTR /* apAppPrivate = 0 */)
       
  1292 	{
       
  1293 	DEBUG_PRINTF2(_L8("COmxILPort::DoBufferAllocation : aSizeBytes[%u]"), aSizeBytes);
       
  1294 
       
  1295 	__ASSERT_DEBUG(aSizeBytes > 0, User::Panic(KOmxILPortPanicCategory, 1));
       
  1296 
       
  1297 	CMMFDescriptorBuffer* pDescBuffer = 0;
       
  1298 	TRAPD(allocRes, pDescBuffer = CMMFDescriptorBuffer::NewL(aSizeBytes));
       
  1299 	if (KErrNone != allocRes)
       
  1300 		{
       
  1301 		return OMX_ErrorInsufficientResources;
       
  1302 		}
       
  1303 
       
  1304 	apPortSpecificBuffer = const_cast<TUint8*>(pDescBuffer->Data().Ptr());
       
  1305 	apPortPrivate		 = static_cast<CMMFBuffer*>(pDescBuffer);
       
  1306 
       
  1307 	return OMX_ErrorNone;
       
  1308 
       
  1309 	}
       
  1310 
       
  1311 /**
       
  1312    This method provides a mechanism for ports to place the port-specific
       
  1313    buffer deallocation logic (typically used in an OMX_FreeBuffer
       
  1314    scenario).
       
  1315 
       
  1316    @param apPortSpecificBuffer A pointer to the memory area to be deallocated
       
  1317    by the port.
       
  1318 
       
  1319    @param apPortPrivate A pointer that refers to a port-specific structure.
       
  1320 
       
  1321    @param apPlatformPrivate A pointer to an optional platform-specific
       
  1322    structure.
       
  1323 
       
  1324    @param apAppPrivate A pointer that refers to a buffer supplier-specific
       
  1325    structure.
       
  1326 
       
  1327 */
       
  1328 EXPORT_C void
       
  1329 COmxILPort::DoBufferDeallocation(OMX_PTR /*apPortSpecificBuffer */,
       
  1330 								 OMX_PTR apPortPrivate,
       
  1331 								 OMX_PTR /* apPlatformPrivate */,
       
  1332 								 OMX_PTR /* apAppPrivate = 0 */)
       
  1333 	{
       
  1334 	DEBUG_PRINTF(_L8("COmxILPort::DoBufferDeallocation"));
       
  1335 
       
  1336 	__ASSERT_DEBUG(apPortPrivate, User::Panic(KOmxILPortPanicCategory, 1));
       
  1337 
       
  1338 	delete reinterpret_cast<CMMFBuffer*>(apPortPrivate);
       
  1339 
       
  1340 	}
       
  1341 
       
  1342 /**
       
  1343    This method provides a mechanism for ports to place the port-specific buffer
       
  1344    wrapping logic (typically used in an OMX_UseBuffer scenario).
       
  1345 
       
  1346    @param aSizeBytes The size in bytes of the buffer to be wrapped.
       
  1347 
       
  1348    @param apBuffer A pointer received from the IL Client or another
       
  1349    component that references the allocated memory area .
       
  1350 
       
  1351    @param [OUT] apPortPrivate A pointer that refers to a port-specific
       
  1352    structure.
       
  1353 
       
  1354    @param [OUT] apPlatformPrivate A pointer to an optional platform-specific
       
  1355    structure.
       
  1356 
       
  1357    @param [OUT] apAppPrivate A pointer that refers to a buffer
       
  1358    supplier-specific structure.
       
  1359 
       
  1360    @return OMX_ERRORTYPE
       
  1361 */
       
  1362 EXPORT_C OMX_ERRORTYPE
       
  1363 COmxILPort::DoBufferWrapping(OMX_U32 aSizeBytes,
       
  1364 							 OMX_U8* apBuffer,
       
  1365 							 OMX_PTR& apPortPrivate,
       
  1366 							 OMX_PTR& /* apPlatformPrivate */,
       
  1367 							 OMX_PTR /* apAppPrivate = 0 */)
       
  1368 	{
       
  1369 	DEBUG_PRINTF(_L8("COmxILPort::DoBufferWrapping"));
       
  1370 
       
  1371 	__ASSERT_DEBUG(aSizeBytes > 0 && apBuffer,
       
  1372 				   User::Panic(KOmxILPortPanicCategory, 1));
       
  1373 
       
  1374 	CMMFBuffer* pMmfBuffer = 0;
       
  1375 	TPtr8 ptr(apBuffer, aSizeBytes, aSizeBytes);
       
  1376 	TRAPD(allocRes, pMmfBuffer = CMMFPtrBuffer::NewL(ptr));
       
  1377 	if (KErrNone != allocRes)
       
  1378 		{
       
  1379 		return OMX_ErrorInsufficientResources;
       
  1380 		}
       
  1381 
       
  1382 	apPortPrivate = pMmfBuffer;
       
  1383 
       
  1384 	return OMX_ErrorNone;
       
  1385 
       
  1386 	}
       
  1387 
       
  1388 /**
       
  1389    This method provides a mechanism for ports to place the port-specific buffer
       
  1390    unwrapping logic (typically used in an OMX_FreeBuffer scenario).
       
  1391 
       
  1392    @param apPortSpecificBuffer A pointer to the allocated memory area.
       
  1393 
       
  1394    @param apPortPrivate A pointer that refers to a port-specific structure.
       
  1395 
       
  1396    @param apPlatformPrivate A pointer to an optional platform-specific
       
  1397    structure.
       
  1398 
       
  1399    @param apAppPrivate A pointer that refers to a buffer supplier-specific
       
  1400    structure.
       
  1401 
       
  1402 */
       
  1403 EXPORT_C void
       
  1404 COmxILPort::DoBufferUnwrapping(OMX_PTR /* apBuffer*/,
       
  1405 							   OMX_PTR appPortPrivate,
       
  1406 							   OMX_PTR /* apPlatformPrivate */,
       
  1407 							   OMX_PTR /* apAppPrivate = 0 */)
       
  1408 	{
       
  1409 
       
  1410 	DEBUG_PRINTF(_L8("COmxILPort::DoBufferUnwrapping"));
       
  1411 
       
  1412 	__ASSERT_DEBUG(appPortPrivate, User::Panic(KOmxILPortPanicCategory, 1));
       
  1413 
       
  1414 	delete reinterpret_cast<CMMFBuffer*>(appPortPrivate);
       
  1415 
       
  1416 	}
       
  1417 
       
  1418 /**
       
  1419    This method gets called during tunnelled buffer allocation (i.e.,
       
  1420    PopulateTunnel). This is to allow component implementations to override this
       
  1421    default implementation in a way that the pAppPrivate pointer parameter of
       
  1422    OMX_UseBuffer can be used to convey pPortPrivate or pPlatformPrivate to the
       
  1423    tunnelled component.
       
  1424 
       
  1425    @param aTunnelledComponent Handle to the tunnelled component
       
  1426 
       
  1427    @param [OUT] appBufferHdr The buffer header that will be allocated by the
       
  1428    tunnelled component
       
  1429 
       
  1430    @param aTunnelledPortIndex The index of the tunnelled port
       
  1431 
       
  1432    @param apPortPrivate pPortPrivate pointer as returned by DoBufferAllocation
       
  1433 
       
  1434    @param apPlatformPrivate pPlatformPrivate pointer as returned by
       
  1435    DoBufferAllocation
       
  1436 
       
  1437    @param aSizeBytes The size in bytes of the to be allocated buffer
       
  1438 
       
  1439    @param apBuffer A pointer to the allocated buffer
       
  1440 
       
  1441    @return OMX_ERRORTYPE
       
  1442 
       
  1443 */
       
  1444 EXPORT_C OMX_ERRORTYPE
       
  1445 COmxILPort::DoOmxUseBuffer(OMX_HANDLETYPE aTunnelledComponent,
       
  1446 						   OMX_BUFFERHEADERTYPE** appBufferHdr,
       
  1447 						   OMX_U32 aTunnelledPortIndex,
       
  1448 						   OMX_PTR /* apPortPrivate */,
       
  1449 						   OMX_PTR /* apPlatformPrivate */,
       
  1450 						   OMX_U32 aSizeBytes,
       
  1451 						   OMX_U8* apBuffer)
       
  1452 	{
       
  1453 
       
  1454 	DEBUG_PRINTF(_L8("COmxILPort::DoOmxUseBuffer"));
       
  1455 
       
  1456 	return OMX_UseBuffer(
       
  1457 		aTunnelledComponent,
       
  1458 		appBufferHdr,
       
  1459 		aTunnelledPortIndex,
       
  1460 		0,
       
  1461 		aSizeBytes,
       
  1462 		apBuffer);
       
  1463 
       
  1464 	}
       
  1465 
       
  1466 EXPORT_C TBool
       
  1467 COmxILPort::TBufferInfo::Compare(const TBufferInfo& aBi1,
       
  1468 								 const TBufferInfo& aBi2)
       
  1469 	{
       
  1470 	return (aBi1.GetHeader() == aBi2.GetHeader() ? ETrue : EFalse);
       
  1471 	}