omxil_generic/omxilcomplib/src/omxilfsm.cpp
changeset 0 0e4a32b9112d
equal deleted inserted replaced
-1:000000000000 0:0e4a32b9112d
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 /**
       
    18  @file
       
    19  @internalComponent
       
    20 */
       
    21 
       
    22 #include "log.h"
       
    23 #include "omxilfsm.h"
       
    24 #include "omxilstate.h"
       
    25 #include <openmax/il/common/omxilconfigmanager.h>
       
    26 #include "omxilcallbackmanager.h"
       
    27 #include <openmax/il/common/omxilprocessingfunction.h>
       
    28 #include "omxilportmanagerif.h"
       
    29 #include "omxilcommand.h"
       
    30 #include <openmax/il/common/omxilstatedefs.h>
       
    31 
       
    32 #define RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(_a)						\
       
    33 	{																	\
       
    34 	const OMX_ERRORTYPE _err = _a;										\
       
    35 	if (OMX_ErrorNone == _err) return _err;								\
       
    36 	else return SendOmxErrorEventIfNeeded(_err);						\
       
    37 	}
       
    38 
       
    39 
       
    40 const TInt COmxILFsm::KMaxMsgQueueEntries;
       
    41 
       
    42 COmxILFsm*
       
    43 COmxILFsm::NewL(COmxILComponent& aComponent,
       
    44 				COmxILProcessingFunction& aProcFunction,
       
    45 				MOmxILPortManagerIf& aPortManager,
       
    46 				COmxILConfigManager& aConfigManager,
       
    47 				MOmxILCallbackManagerIf& aCallbacks)
       
    48 	{
       
    49     DEBUG_PRINTF(_L8("COmxILFsm::NewLC"));
       
    50 
       
    51 	COmxILFsm* self = new (ELeave) COmxILFsm(aComponent,
       
    52 											 aProcFunction,
       
    53 											 aPortManager,
       
    54 											 aConfigManager,
       
    55 											 aCallbacks);
       
    56 	CleanupStack::PushL(self);
       
    57 	self->ConstructL();
       
    58 	CleanupStack::Pop(self);
       
    59 	return (self);
       
    60 	}
       
    61 
       
    62 void
       
    63 COmxILFsm::ConstructL()
       
    64 	{
       
    65     DEBUG_PRINTF(_L8("COmxILFsm::ConstructL"));
       
    66 
       
    67 	// Create the FSM states
       
    68 
       
    69 	// Init the array
       
    70 	for (TUint i=0; i < EStateMax; ++i)
       
    71 		{
       
    72 		iStates.AppendL(NULL);
       
    73 		}
       
    74 
       
    75 	// Add the standard states...
       
    76 	iStates[EStateInvalid]			= new (ELeave)COmxILStateInvalid;
       
    77 	iStates[EStateLoaded]			= new (ELeave)COmxILStateLoaded;
       
    78 	iStates[EStateIdle]				= new (ELeave)COmxILStateIdle;
       
    79 	iStates[EStateExecuting]		= new (ELeave)COmxILStateExecuting;
       
    80 	iStates[EStatePause]			= new (ELeave)COmxILStatePause;
       
    81 	iStates[EStateWaitForResources] = new (ELeave)COmxILStateWaitForResources;
       
    82 
       
    83 	// Now add the substates
       
    84 	iStates[ESubStateLoadedToIdle]	  = new (ELeave)COmxILStateLoadedToIdle;
       
    85 	iStates[ESubStateIdleToLoaded]	  = new (ELeave)COmxILStateIdleToLoaded;
       
    86 	iStates[ESubStateExecutingToIdle] = new (ELeave)COmxILStateExecutingToIdle;
       
    87 	iStates[ESubStatePauseToIdle]	  = new (ELeave)COmxILStatePauseToIdle;
       
    88 
       
    89 	iCallbacks.SetPortManager(iPortManager);
       
    90 	iCallbacks.SetFsm(*this);
       
    91 
       
    92 	}
       
    93 
       
    94 COmxILFsm::COmxILFsm(COmxILComponent& aComponent,
       
    95 					 COmxILProcessingFunction& aProcFunction,
       
    96 					 MOmxILPortManagerIf& aPortManager,
       
    97 					 COmxILConfigManager& aConfigManager,
       
    98 					 MOmxILCallbackManagerIf& aCallbacks)
       
    99 	:
       
   100 	iComponent(aComponent),
       
   101 	iProcFunction(aProcFunction),
       
   102 	iPortManager(aPortManager),
       
   103 	iConfigManager(aConfigManager),
       
   104 	iCallbacks(aCallbacks),
       
   105 	iStates(),
       
   106 	iCurrentStateIndex(EStateMax),
       
   107 	ipCurrentState(0)
       
   108 	{
       
   109     DEBUG_PRINTF(_L8("COmxILFsm::COmxILFsm"));
       
   110 	}
       
   111 
       
   112 COmxILFsm::~COmxILFsm()
       
   113 	{
       
   114     DEBUG_PRINTF(_L8("COmxILFsm::~COmxILFsm"));
       
   115 
       
   116 	iCurrentStateIndex = EStateMax;
       
   117 	ipCurrentState = 0;
       
   118 	iStates.ResetAndDestroy();
       
   119 
       
   120 	}
       
   121 
       
   122 OMX_ERRORTYPE
       
   123 COmxILFsm::InitFsm()
       
   124 	{
       
   125     DEBUG_PRINTF(_L8("COmxILFsm::InitFsm"));
       
   126 
       
   127 	// Let's get ready to handle API calls...
       
   128 	iCurrentStateIndex = EStateLoaded;
       
   129 	ipCurrentState	   = iStates[iCurrentStateIndex];
       
   130 	return OMX_ErrorNone;
       
   131 
       
   132 	}
       
   133 
       
   134 COmxILComponent*
       
   135 COmxILFsm::GetComponent() const
       
   136 	{
       
   137 	return &iComponent;
       
   138 	}
       
   139 
       
   140 OMX_ERRORTYPE
       
   141 COmxILFsm::PopulateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr,
       
   142 						  OMX_U32 aPortIndex,
       
   143 						  OMX_PTR apAppPrivate,
       
   144 						  OMX_U32 aSizeBytes,
       
   145 						  OMX_U8* apBuffer)
       
   146 	{
       
   147     DEBUG_PRINTF(_L8("COmxILFsm::PopulateBuffer"));
       
   148 
       
   149 	TBool portPopulationCompleted = EFalse;
       
   150 	OMX_ERRORTYPE omxRetValue =
       
   151 		ipCurrentState->PopulateBuffer(*this,
       
   152 									   appBufferHdr,
       
   153 									   aPortIndex,
       
   154 									   apAppPrivate,
       
   155 									   aSizeBytes,
       
   156 									   apBuffer,
       
   157 									   portPopulationCompleted);
       
   158 
       
   159 	if (OMX_ErrorNone == omxRetValue)
       
   160 		{
       
   161 		if (portPopulationCompleted &&
       
   162 			ESubStateLoadedToIdle == iCurrentStateIndex &&
       
   163 			iPortManager.AllPortsPopulated())
       
   164 			{
       
   165 			// Complete here the transition to OMX_StateIdle
       
   166 			omxRetValue = FsmTransition(EStateIdle);
       
   167 			if (OMX_ErrorNone == omxRetValue)
       
   168 				{
       
   169 				// Notify the IL client that port population has
       
   170 				// completed sucessfully
       
   171 				omxRetValue = iCallbacks.TransitionCompleteNotification(
       
   172 					OMX_StateIdle);
       
   173 
       
   174 				}
       
   175 			}
       
   176 		}
       
   177 
       
   178 	if (OMX_ErrorNone == omxRetValue ||
       
   179 		OMX_ErrorInsufficientResources == omxRetValue)
       
   180 		{
       
   181 		// OMX_ErrorInsufficientResources is allowed in OMX_EmptyThisBuffer and
       
   182 		// OMX_FillThisBuffer
       
   183 		return omxRetValue;
       
   184 		}
       
   185 	else
       
   186 		{
       
   187 		return SendOmxErrorEventIfNeeded(omxRetValue);
       
   188 		}
       
   189 
       
   190 	}
       
   191 
       
   192 OMX_ERRORTYPE
       
   193 COmxILFsm::FsmTransition(TStateIndex aNewState)
       
   194 	{
       
   195     DEBUG_PRINTF2(_L8("COmxILFsm::FsmTransition : %d"), aNewState);
       
   196 
       
   197 	__ASSERT_ALWAYS(aNewState < EStateMax,
       
   198 					User::Panic(KOmxILFsmPanicCategory, 1));
       
   199 
       
   200 	if (aNewState != iCurrentStateIndex)
       
   201 		{
       
   202 		// We notify the processing function of all the state transitions, even
       
   203 		// if they are not to a final OpenMAX IL state.
       
   204 		OMX_ERRORTYPE omxRetValue;
       
   205 		if (OMX_ErrorNone !=
       
   206 			(omxRetValue =
       
   207 			 iProcFunction.StateTransitionIndication(aNewState)))
       
   208 			{
       
   209 			// No need of propagating further error codes if the component is
       
   210 			// transitioning to OMX_StateInvalid or if the PF itself is
       
   211 			// invalidating the component...
       
   212 			if (EStateInvalid != aNewState &&
       
   213 				OMX_ErrorInvalidState != omxRetValue)
       
   214 				{
       
   215 				return omxRetValue;
       
   216 				}
       
   217 			}
       
   218 
       
   219 		iCurrentStateIndex = aNewState;
       
   220 		ipCurrentState = iStates[iCurrentStateIndex];
       
   221 
       
   222 		}
       
   223 
       
   224 	return OMX_ErrorNone;
       
   225 
       
   226 	}
       
   227 
       
   228 OMX_ERRORTYPE
       
   229 COmxILFsm::FsmTransition(TUint32 aNewState)
       
   230 	{
       
   231 
       
   232 	return FsmTransition(static_cast<TStateIndex>(aNewState));
       
   233 
       
   234 	}
       
   235 
       
   236 
       
   237 OMX_ERRORTYPE
       
   238 COmxILFsm::GetComponentVersion(OMX_STRING aComponentName,
       
   239 							   OMX_VERSIONTYPE* apComponentVersion,
       
   240 							   OMX_VERSIONTYPE* apSpecVersion,
       
   241 							   OMX_UUIDTYPE* apComponentUUID) const
       
   242 	{
       
   243     DEBUG_PRINTF(_L8("COmxILFsm::GetComponentVersion"));
       
   244 
       
   245 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   246 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   247 
       
   248 	// This api should not be allowed in OMX_StateInvalid
       
   249 	if (EStateInvalid == iCurrentStateIndex)
       
   250 		{
       
   251 		return SendOmxErrorEventIfNeeded(OMX_ErrorInvalidState);
       
   252 		}
       
   253 
       
   254 	if (!aComponentName ||
       
   255 		!apComponentVersion ||
       
   256 		!apSpecVersion ||
       
   257 		!apComponentUUID)
       
   258 		{
       
   259 		return OMX_ErrorBadParameter;
       
   260 		}
       
   261 
       
   262 	// This API call is independent of the current state. Its handled by the
       
   263 	// the config manager
       
   264 
       
   265 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   266 		iConfigManager.GetComponentVersion(
       
   267 			aComponentName,
       
   268 			apComponentVersion,
       
   269 			apSpecVersion,
       
   270 			apComponentUUID));
       
   271 	}
       
   272 
       
   273 
       
   274 OMX_ERRORTYPE
       
   275 COmxILFsm::SendCommand(OMX_COMMANDTYPE aCommand,
       
   276 					   TUint32 anParam1,
       
   277 					   TAny* apCmdData)
       
   278 	{
       
   279     DEBUG_PRINTF3(_L8("COmxILFsm::SendCommand : command [%d] Param1 [%d]"), aCommand, anParam1);
       
   280 
       
   281 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   282 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   283 
       
   284 	// Do some very minor error checking here to try to save some time...
       
   285 	if (OMX_CommandStateSet == aCommand &&
       
   286 		anParam1 > OMX_StateWaitForResources)
       
   287 		{
       
   288 		return OMX_ErrorBadParameter;
       
   289 		}
       
   290 
       
   291 	TOmxILCommand command(aCommand, anParam1, apCmdData);
       
   292 	OMX_ERRORTYPE sendCommandError;
       
   293 	switch (aCommand)
       
   294 		{
       
   295 	case OMX_CommandStateSet:
       
   296 		{
       
   297 		sendCommandError = ipCurrentState->CommandStateSet(*this, command);
       
   298 		}
       
   299 		break;
       
   300 	case OMX_CommandFlush:
       
   301 		{
       
   302 		sendCommandError = ipCurrentState->CommandFlush(*this, command);
       
   303 		}
       
   304 		break;
       
   305 	case OMX_CommandPortDisable:
       
   306 		{
       
   307 		sendCommandError = ipCurrentState->CommandPortDisable(*this, command);
       
   308 		}
       
   309 		break;
       
   310 	case OMX_CommandPortEnable:
       
   311 		{
       
   312 		sendCommandError = ipCurrentState->CommandPortEnable(*this, command);
       
   313 		}
       
   314 		break;
       
   315 	case OMX_CommandMarkBuffer:
       
   316 		{
       
   317 		sendCommandError = ipCurrentState->CommandMarkBuffer(*this, command);
       
   318 		}
       
   319 		break;
       
   320 	default:
       
   321 		{
       
   322 		// This is an invalid command type
       
   323 		return OMX_ErrorBadParameter;
       
   324 		}
       
   325 		};
       
   326 
       
   327 	if (OMX_ErrorNone == sendCommandError ||
       
   328 		OMX_ErrorInsufficientResources == sendCommandError)
       
   329 		{
       
   330 		// OMX_ErrorInsufficientResources is allowed in OMX_SendCommand
       
   331 		return sendCommandError;
       
   332 		}
       
   333 	else
       
   334 		{
       
   335 		return SendOmxErrorEventIfNeeded(sendCommandError);
       
   336 		}
       
   337 
       
   338 	}
       
   339 
       
   340 
       
   341 OMX_ERRORTYPE
       
   342 COmxILFsm::GetParameter(OMX_INDEXTYPE aParamIndex,
       
   343 						TAny* apComponentParameterStructure) const
       
   344 	{
       
   345     DEBUG_PRINTF(_L8("COmxILFsm::GetParameter"));
       
   346 
       
   347 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   348 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   349 
       
   350 	if (!apComponentParameterStructure)
       
   351 		{
       
   352 		return OMX_ErrorBadParameter;
       
   353 		}
       
   354 
       
   355 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   356 		ipCurrentState->GetParameter(*this, aParamIndex,
       
   357 									 apComponentParameterStructure));
       
   358 	}
       
   359 
       
   360 
       
   361 OMX_ERRORTYPE
       
   362 COmxILFsm::SetParameter(OMX_INDEXTYPE aParamIndex,
       
   363 						const TAny* apComponentParameterStructure)
       
   364 	{
       
   365     DEBUG_PRINTF(_L8("COmxILFsm::SetParameter"));
       
   366 
       
   367 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   368 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   369 
       
   370 	if (!apComponentParameterStructure)
       
   371 		{
       
   372 		return OMX_ErrorBadParameter;
       
   373 		}
       
   374 
       
   375 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   376 	ipCurrentState->SetParameter(*this, aParamIndex,
       
   377 								 apComponentParameterStructure));
       
   378 	}
       
   379 
       
   380 
       
   381 OMX_ERRORTYPE
       
   382 COmxILFsm::GetConfig(OMX_INDEXTYPE aConfigIndex,
       
   383 					 TAny* apComponentConfigStructure) const
       
   384 	{
       
   385     DEBUG_PRINTF(_L8("COmxILFsm::GetConfig"));
       
   386 
       
   387 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   388 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   389 
       
   390 	if (!apComponentConfigStructure)
       
   391 		{
       
   392 		return OMX_ErrorBadParameter;
       
   393 		}
       
   394 
       
   395 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   396 		ipCurrentState->GetConfig(*this,
       
   397 								  aConfigIndex,
       
   398 								  apComponentConfigStructure));
       
   399 
       
   400 	}
       
   401 
       
   402 
       
   403 OMX_ERRORTYPE
       
   404 COmxILFsm::SetConfig(OMX_INDEXTYPE aIndex,
       
   405 					 const TAny* apComponentConfigStructure)
       
   406 	{
       
   407     DEBUG_PRINTF(_L8("COmxILFsm::SetConfig"));
       
   408 
       
   409 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   410 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   411 
       
   412 	if (!apComponentConfigStructure)
       
   413 		{
       
   414 		return OMX_ErrorBadParameter;
       
   415 		}
       
   416 
       
   417 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   418 		ipCurrentState->SetConfig(*this, aIndex, apComponentConfigStructure));
       
   419 
       
   420 	}
       
   421 
       
   422 
       
   423 OMX_ERRORTYPE
       
   424 COmxILFsm::GetExtensionIndex(
       
   425 	OMX_STRING aParameterName,
       
   426 	OMX_INDEXTYPE* apIndexType) const
       
   427 	{
       
   428     DEBUG_PRINTF(_L8("COmxILFsm::GetExtensionIndex"));
       
   429 
       
   430 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   431 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   432 
       
   433 	if (!apIndexType || !aParameterName)
       
   434 		{
       
   435 		return OMX_ErrorBadParameter;
       
   436 		}
       
   437 
       
   438 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   439 		ipCurrentState->GetExtensionIndex(*this,
       
   440 										  aParameterName,
       
   441 										  apIndexType));
       
   442 	}
       
   443 
       
   444 
       
   445 OMX_ERRORTYPE
       
   446 COmxILFsm::GetState(OMX_STATETYPE* apState) const
       
   447 	{
       
   448     DEBUG_PRINTF(_L8("COmxILFsm::GetState"));
       
   449 
       
   450 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   451 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   452 
       
   453 	if (!apState)
       
   454 		{
       
   455 		return OMX_ErrorBadParameter;
       
   456 		}
       
   457 
       
   458 	*apState = ipCurrentState->GetState();
       
   459 
       
   460 	return OMX_ErrorNone;
       
   461 
       
   462 	}
       
   463 
       
   464 
       
   465 OMX_ERRORTYPE
       
   466 COmxILFsm::ComponentTunnelRequest(OMX_U32 aPort,
       
   467 								  OMX_HANDLETYPE aTunneledComp,
       
   468 								  OMX_U32 aTunneledPort,
       
   469 								  OMX_TUNNELSETUPTYPE* apTunnelSetup)
       
   470 	{
       
   471     DEBUG_PRINTF(_L8("COmxILFsm::ComponentTunnelRequest"));
       
   472 
       
   473 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   474 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   475 
       
   476 	// Here, since NULL is a valid parameter for aTunneledComp, checking of
       
   477 	// input parameters is completely done by the ports.
       
   478 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   479 		ipCurrentState->ComponentTunnelRequest(*this,
       
   480 											   aPort,
       
   481 											   aTunneledComp,
       
   482 											   aTunneledPort,
       
   483 											   apTunnelSetup));
       
   484 
       
   485 	}
       
   486 
       
   487 
       
   488 OMX_ERRORTYPE
       
   489 COmxILFsm::UseBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr,
       
   490 					 OMX_U32 aPortIndex,
       
   491 					 OMX_PTR apAppPrivate,
       
   492 					 OMX_U32 aSizeBytes,
       
   493 					 OMX_U8* apBuffer)
       
   494 	{
       
   495     DEBUG_PRINTF(_L8("COmxILFsm::UseBuffer"));
       
   496 
       
   497 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   498 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   499 
       
   500 	if (!appBufferHdr || !aSizeBytes || !apBuffer)
       
   501 		{
       
   502 		return OMX_ErrorBadParameter;
       
   503 		}
       
   504 
       
   505 	return PopulateBuffer(appBufferHdr,
       
   506 						  aPortIndex,
       
   507 						  apAppPrivate,
       
   508 						  aSizeBytes,
       
   509 						  apBuffer);
       
   510 
       
   511 	}
       
   512 
       
   513 
       
   514 OMX_ERRORTYPE
       
   515 COmxILFsm::AllocateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr,
       
   516 						  OMX_U32 aPortIndex,
       
   517 						  OMX_PTR apAppPrivate,
       
   518 						  OMX_U32 aSizeBytes)
       
   519 	{
       
   520     DEBUG_PRINTF(_L8("COmxILFsm::AllocateBuffer"));
       
   521 
       
   522 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   523 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   524 
       
   525 	if (!appBufferHdr || !aSizeBytes)
       
   526 		{
       
   527 		return OMX_ErrorBadParameter;
       
   528 		}
       
   529 
       
   530 
       
   531 	return PopulateBuffer(appBufferHdr,
       
   532 						  aPortIndex,
       
   533 						  apAppPrivate,
       
   534 						  aSizeBytes,
       
   535 						  0);
       
   536 
       
   537 	}
       
   538 
       
   539 
       
   540 OMX_ERRORTYPE
       
   541 COmxILFsm::FreeBuffer(OMX_U32 aPortIndex,
       
   542 					  OMX_BUFFERHEADERTYPE* apBuffer)
       
   543 	{
       
   544     DEBUG_PRINTF(_L8("COmxILFsm::FreeBuffer"));
       
   545 
       
   546 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   547 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   548 
       
   549 	if (!apBuffer)
       
   550 		{
       
   551 		return OMX_ErrorBadParameter;
       
   552 		}
       
   553 
       
   554 	TBool portDepopulationCompleted = EFalse;
       
   555 	OMX_ERRORTYPE omxRetValue =
       
   556 		ipCurrentState->FreeBuffer(*this,
       
   557 								   aPortIndex,
       
   558 								   apBuffer,
       
   559 								   portDepopulationCompleted);
       
   560 
       
   561 	if (OMX_ErrorNone == omxRetValue)
       
   562 		{
       
   563 		if (portDepopulationCompleted)
       
   564 			{
       
   565 			if (ESubStateIdleToLoaded == iCurrentStateIndex)
       
   566 				{
       
   567 				if (iPortManager.AllPortsDePopulated())
       
   568 					{
       
   569 					// Complete here the transition to OMX_StateLoaded
       
   570 					omxRetValue = FsmTransition(EStateLoaded);
       
   571 					if (OMX_ErrorNone == omxRetValue)
       
   572 						{
       
   573 						// Notify the IL client that port depopulation has
       
   574 						// completed sucessfully
       
   575 						omxRetValue =
       
   576 							iCallbacks.TransitionCompleteNotification(
       
   577 							OMX_StateLoaded);
       
   578 						}
       
   579 					}
       
   580 				}
       
   581 			}
       
   582 		}
       
   583 
       
   584 	if (OMX_ErrorNone == omxRetValue)
       
   585 		{
       
   586 		return OMX_ErrorNone;
       
   587 		}
       
   588 	else
       
   589 		{
       
   590 		return SendOmxErrorEventIfNeeded(omxRetValue);
       
   591 		}
       
   592 
       
   593 	}
       
   594 
       
   595 
       
   596 OMX_ERRORTYPE
       
   597 COmxILFsm::EmptyThisBuffer(OMX_BUFFERHEADERTYPE* apBuffer)
       
   598 	{
       
   599     DEBUG_PRINTF2(_L8("COmxILFsm::EmptyThisBuffer : BUFFER [%X]"), apBuffer);
       
   600 
       
   601 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   602 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   603 
       
   604 	if (!apBuffer)
       
   605 		{
       
   606 		return OMX_ErrorBadParameter;
       
   607 		}
       
   608 
       
   609 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   610 		ipCurrentState->EmptyThisBuffer(*this, apBuffer));
       
   611 
       
   612 	}
       
   613 
       
   614 
       
   615 OMX_ERRORTYPE
       
   616 COmxILFsm::FillThisBuffer(OMX_BUFFERHEADERTYPE* apBuffer)
       
   617 	{
       
   618     DEBUG_PRINTF2(_L8("COmxILFsm::FillThisBuffer : BUFFER [%X]"), apBuffer);
       
   619 
       
   620 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   621 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   622 
       
   623 	if (!apBuffer)
       
   624 		{
       
   625 		return OMX_ErrorBadParameter;
       
   626 		}
       
   627 
       
   628 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   629 		ipCurrentState->FillThisBuffer(*this, apBuffer));
       
   630 
       
   631 	}
       
   632 
       
   633 
       
   634 OMX_ERRORTYPE
       
   635 COmxILFsm::SetCallbacks(const OMX_CALLBACKTYPE* apCallbacks,
       
   636 						const OMX_PTR apAppData)
       
   637 	{
       
   638     DEBUG_PRINTF(_L8("COmxILFsm::SetCallbacks"));
       
   639 
       
   640 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   641 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   642 
       
   643 	if (!apCallbacks)
       
   644 		{
       
   645 		return OMX_ErrorBadParameter;
       
   646 		}
       
   647 
       
   648 	// This api should only be allowed in OMX_StateLoaded
       
   649 	if (EStateLoaded != iCurrentStateIndex)
       
   650 		{
       
   651 		return OMX_ErrorIncorrectStateOperation;
       
   652 		}
       
   653 
       
   654 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   655 		iCallbacks.RegisterILClientCallbacks(apCallbacks, apAppData));
       
   656 
       
   657 	}
       
   658 
       
   659 
       
   660 OMX_ERRORTYPE
       
   661 COmxILFsm::UseEGLImage(OMX_BUFFERHEADERTYPE** /*appBufferHdr*/,
       
   662 					   OMX_U32 /*aPortIndex*/,
       
   663 					   OMX_PTR /*aAppPrivate*/,
       
   664 					   void* /*eglImage*/)
       
   665 	{
       
   666     DEBUG_PRINTF(_L8("COmxILFsm::UseEGLImage"));
       
   667 
       
   668 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   669 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   670 
       
   671 	return OMX_ErrorNotImplemented;
       
   672 	}
       
   673 
       
   674 OMX_ERRORTYPE
       
   675 COmxILFsm::ComponentRoleEnum(OMX_U8* aRole,
       
   676 							 OMX_U32 aIndex) const
       
   677 	{
       
   678     DEBUG_PRINTF(_L8("COmxILFsm::ComponentRoleEnum"));
       
   679 
       
   680 	__ASSERT_DEBUG(iCurrentStateIndex != EStateMax,
       
   681 				   User::Panic(KOmxILFsmPanicCategory, 1));
       
   682 
       
   683 	// This api should not be allowed in OMX_StateInvalid
       
   684 	if (EStateInvalid == iCurrentStateIndex)
       
   685 		{
       
   686 		return SendOmxErrorEventIfNeeded(OMX_ErrorInvalidState);
       
   687 		}
       
   688 
       
   689 	if (!aRole)
       
   690 		{
       
   691 		return OMX_ErrorBadParameter;
       
   692 		}
       
   693 
       
   694 	RETURN_OMX_ERROR_AND_EVENT_IF_NEEDED(
       
   695 		iConfigManager.ComponentRoleEnum(aRole,
       
   696 										 aIndex));
       
   697 
       
   698 	}
       
   699 
       
   700 /**
       
   701    This method is here to fullfill the following functionalities:
       
   702 
       
   703    -# It is used to make sure that the component error codes are returned to
       
   704       the IL Client in a way that conforms with Table 3-9 of the OpenMAX IL
       
   705       1.1.1 spec. This table specifies which error codes must be sent with
       
   706       EventHandler. If an error code is to be sent via EventHandler, the API
       
   707       return code must be OMX_ErrorNone.
       
   708 
       
   709    -# This method is also used to invalidate the component whenever an internal
       
   710       component action returns OMX_ErrorInvalidState. For example, this is
       
   711       useful when code executed by a port or by the processing function cannot
       
   712       recover from an internal error. Returning OMX_ErrorInvalidState in that
       
   713       kind of situation will invalidate the component in
       
   714       SendOmxErrorEventIfNeeded and the event will be conveyed to the IL Client
       
   715       as mandated by the spec.
       
   716 
       
   717    @param aError An OpenMAX IL error code.
       
   718  */
       
   719 OMX_ERRORTYPE
       
   720 COmxILFsm::SendOmxErrorEventIfNeeded(OMX_ERRORTYPE aError)
       
   721 	{
       
   722 	DEBUG_PRINTF2(_L8("COmxILFsm::SendOmxErrorEventIfNeeded - aError = 0x%X"), aError);
       
   723 
       
   724 	OMX_ERRORTYPE returnError = aError;
       
   725 	switch(aError)
       
   726 		{
       
   727 	case OMX_ErrorInsufficientResources:
       
   728 		{
       
   729 		DEBUG_PRINTF(_L8("COmxILFsm::SendOmxErrorEventIfNeeded aError[OMX_ErrorInsufficientResources]"));
       
   730 		iCallbacks.ErrorEventNotification(aError);
       
   731 		}
       
   732 		break;
       
   733 	case OMX_ErrorInvalidState:
       
   734 		{
       
   735 		DEBUG_PRINTF(_L8("COmxILFsm::SendOmxErrorEventIfNeeded aError[OMX_ErrorInvalidState]"));
       
   736 		iCallbacks.ErrorEventNotification(aError);
       
   737 		if (EStateInvalid != iCurrentStateIndex)
       
   738 			{
       
   739 			returnError = OMX_ErrorNone;
       
   740 			}
       
   741 		}
       
   742 		break;
       
   743 	case OMX_ErrorUnderflow:
       
   744 	case OMX_ErrorOverflow:
       
   745 	case OMX_ErrorHardware:
       
   746 	case OMX_ErrorStreamCorrupt:
       
   747 	case OMX_ErrorResourcesLost:
       
   748 	case OMX_ErrorSameState:
       
   749 	case OMX_ErrorResourcesPreempted:
       
   750 	case OMX_ErrorPortUnresponsiveDuringAllocation:
       
   751 	case OMX_ErrorPortUnresponsiveDuringDeallocation:
       
   752 	case OMX_ErrorPortUnresponsiveDuringStop:
       
   753 	case OMX_ErrorIncorrectStateTransition:
       
   754 	case OMX_ErrorPortUnpopulated:
       
   755 	case OMX_ErrorDynamicResourcesUnavailable:
       
   756 	case OMX_ErrorMbErrorsInFrame:
       
   757 	case OMX_ErrorFormatNotDetected:
       
   758 		{
       
   759 		DEBUG_PRINTF2(_L8("COmxILFsm::SendOmxErrorEventIfNeeded aError[%X]"), aError);
       
   760 		iCallbacks.ErrorEventNotification(aError);
       
   761 		returnError = OMX_ErrorNone;
       
   762 		}
       
   763 		break;
       
   764 		};
       
   765 
       
   766 	if(OMX_ErrorInvalidState == aError &&
       
   767 	   EStateInvalid != iCurrentStateIndex)
       
   768 		{
       
   769 		// Invalidate this component. This instance of the component should be
       
   770 		// destroyed by the IL Client after this. No need to check error code.
       
   771 		FsmTransition(EStateInvalid);
       
   772 		}
       
   773 
       
   774 	return returnError;
       
   775 
       
   776 	}
       
   777 
       
   778 OMX_ERRORTYPE
       
   779 COmxILFsm::SendOmxErrorEventIfNeeded(OMX_ERRORTYPE aError) const
       
   780 	{
       
   781 	DEBUG_PRINTF(_L8("COmxILFsm::SendOmxErrorEventIfNeeded"));
       
   782 
       
   783 	return const_cast<COmxILFsm*>(this)->SendOmxErrorEventIfNeeded(aError);
       
   784 
       
   785 	}