omxil/omxilcomponentcommon/src/common/omxilcallbackmanager.cpp
changeset 0 40261b775718
child 16 eedf2dcd43c6
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     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 "omxilcallbackmanager.h"
       
    24 #include "omxilportmanager.h"
       
    25 #include "omxilfsm.h"
       
    26 #include "omxilutil.h"
       
    27 
       
    28 const TInt COmxILCallbackManager::KMaxMsgQueueEntries;
       
    29 
       
    30 
       
    31 EXPORT_C COmxILCallbackManager*
       
    32 COmxILCallbackManager::NewL(
       
    33 	OMX_HANDLETYPE apComponentHandle,
       
    34 	OMX_PTR apAppData,
       
    35 	OMX_CALLBACKTYPE* apCallbacks)
       
    36 	{
       
    37     DEBUG_PRINTF(_L8("COmxILCallbackManager::NewL"));
       
    38 	COmxILCallbackManager* self = new (ELeave)COmxILCallbackManager(
       
    39 		apComponentHandle,
       
    40 		apAppData,
       
    41 		apCallbacks);
       
    42 	CleanupStack::PushL(self);
       
    43 	self->ConstructL();
       
    44 	CleanupStack::Pop(self);
       
    45 	return self;
       
    46 	}
       
    47 
       
    48 void
       
    49 COmxILCallbackManager::ConstructL()
       
    50 	{
       
    51     DEBUG_PRINTF(_L8("COmxILCallbackManager::ConstructL"));
       
    52 
       
    53 	CActiveScheduler::Add(this);
       
    54 	User::LeaveIfError(iCommandQueue.CreateLocal(KMaxMsgQueueEntries));
       
    55 	iCommandQueue.NotifyDataAvailable(iStatus);
       
    56 
       
    57 	User::LeaveIfError(iPendingQueue.CreateLocal(KMaxMsgQueueEntries));
       
    58 
       
    59 	SetActive();
       
    60 
       
    61 	}
       
    62 
       
    63 COmxILCallbackManager::COmxILCallbackManager(OMX_HANDLETYPE apComponentHandle,
       
    64 											 OMX_PTR apAppData,
       
    65 											 OMX_CALLBACKTYPE* apCallbacks)
       
    66 	:
       
    67 	CActive(CActive::EPriorityStandard),
       
    68 	XOmxILCallbackManagerIfImpl(
       
    69 		static_cast<OMX_COMPONENTTYPE*>(apComponentHandle),
       
    70 		apAppData,
       
    71 		apCallbacks),
       
    72 	iCommandQueue(),
       
    73 	iPendingQueue(),
       
    74 	iFlushPendingQueue(EFalse),
       
    75 	iCurrentState(OMX_StateLoaded),
       
    76 	iPreviousState(OMX_StateLoaded)
       
    77 	{
       
    78     DEBUG_PRINTF(_L8("COmxILCallbackManager::COmxILCallbackManager"));
       
    79 	}
       
    80 
       
    81 EXPORT_C
       
    82 COmxILCallbackManager::~COmxILCallbackManager()
       
    83 	{
       
    84     DEBUG_PRINTF(_L8("COmxILCallbackManager::~COmxILCallbackManager"));
       
    85 
       
    86 	Cancel();
       
    87 
       
    88 	CleanUpQueue(iPendingQueue);
       
    89 
       
    90 	CleanUpQueue(iCommandQueue);
       
    91 
       
    92 	}
       
    93 
       
    94 
       
    95 void
       
    96 COmxILCallbackManager::CleanUpQueue(RCallbackManagerQueue& aQueue)
       
    97 	{
       
    98     DEBUG_PRINTF(_L8("COmxILCallbackManager::CleanUpQueue"));
       
    99 
       
   100 	if (aQueue.Handle() != 0)
       
   101 		{
       
   102 		CCallbackCommand* pCommand = 0;
       
   103 		TInt err = KErrNone;
       
   104 		while ((err = aQueue.Receive(pCommand)) == KErrNone)
       
   105 			{
       
   106 			DEBUG_PRINTF2(_L8("COmxILCallbackManager::CleanUpQueue : aQueue.Receive [%X]"), pCommand);
       
   107 			delete pCommand;
       
   108 			pCommand = 0;
       
   109 			}
       
   110 
       
   111 		if (KErrNone != err)
       
   112 			{
       
   113 			DEBUG_PRINTF2(_L8("COmxILCallbackManager::CleanUpQueue : aQueue.Receive returned error [%d]"), err);
       
   114 			if (KErrNoMemory == err)
       
   115 				{
       
   116 				HandleInsufficientResources();
       
   117 				}
       
   118 			}
       
   119 
       
   120 		}
       
   121 
       
   122 	aQueue.Close();
       
   123 
       
   124 	}
       
   125 
       
   126 
       
   127 EXPORT_C void
       
   128 COmxILCallbackManager::SetPortManager(COmxILPortManager& apPortManager)
       
   129 	{
       
   130 	DoSetPortManager(apPortManager);
       
   131 	}
       
   132 
       
   133 EXPORT_C void
       
   134 COmxILCallbackManager::SetFsm(COmxILFsm& apFsm)
       
   135 	{
       
   136 	DoSetFsm(apFsm);
       
   137 	}
       
   138 
       
   139 EXPORT_C OMX_ERRORTYPE
       
   140 COmxILCallbackManager::RegisterComponentHandle(OMX_HANDLETYPE aComponentHandle)
       
   141 	{
       
   142     DEBUG_PRINTF(_L8("COmxILCallbackManager::RegisterComponentHandle"));
       
   143 
       
   144 	__ASSERT_DEBUG(aComponentHandle,
       
   145 				   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   146 
       
   147 	CCompHandleRegistrationCommand* pHandleReg =
       
   148 		new CCompHandleRegistrationCommand(aComponentHandle);
       
   149 	if (!pHandleReg || (iCommandQueue.Send(pHandleReg) != KErrNone))
       
   150 		{
       
   151 		delete pHandleReg;
       
   152 		DoRegisterComponentHandle(aComponentHandle);
       
   153 		return OMX_ErrorInsufficientResources;
       
   154 		}
       
   155 
       
   156 	return OMX_ErrorNone;
       
   157 
       
   158 	}
       
   159 
       
   160 /**
       
   161    The IL Client callback registration is handled in this implementation
       
   162    asynchronously. Note that this implementation assumes that the IL Client
       
   163    will update the callbacks information once all expected callbacks from this
       
   164    component have already been received and therefore, the callback change will
       
   165    be safe leading to no race condition at the IL Client side.
       
   166 
       
   167    @param apCallbacks The IL Client callback structure.
       
   168 
       
   169    @param apAppData Pointer to an application provided value so that the
       
   170 	    application can have a component specific context when receiving
       
   171 	    the callback.
       
   172 
       
   173    @return OMX_ERRORTYPE
       
   174  */
       
   175 EXPORT_C OMX_ERRORTYPE
       
   176 COmxILCallbackManager::RegisterILClientCallbacks(
       
   177 	const OMX_CALLBACKTYPE* apCallbacks,
       
   178 	const OMX_PTR apAppData)
       
   179 	{
       
   180     DEBUG_PRINTF(_L8("COmxILCallbackManager::RegisterILClientCallbacks"));
       
   181 
       
   182 	CClientCallbacksRegistrationCommand* pClientCBacksReg =
       
   183 		new CClientCallbacksRegistrationCommand(
       
   184 			apCallbacks,
       
   185 			apAppData);
       
   186 	if (!pClientCBacksReg || (iCommandQueue.Send(pClientCBacksReg) != KErrNone))
       
   187 		{
       
   188 		delete pClientCBacksReg;
       
   189 		DoRegisterILClientCallbacks(apCallbacks, apAppData);
       
   190 		return OMX_ErrorInsufficientResources;
       
   191 		}
       
   192 
       
   193 	return OMX_ErrorNone;
       
   194 
       
   195 	}
       
   196 
       
   197 EXPORT_C OMX_ERRORTYPE
       
   198 COmxILCallbackManager::RegisterTunnelCallback(
       
   199 	OMX_U32 aLocalPortIndex,
       
   200 	OMX_DIRTYPE aLocalPortDirection,
       
   201 	OMX_HANDLETYPE aTunnelledComponentHandle,
       
   202 	OMX_U32 aTunnelledPortIndex)
       
   203 	{
       
   204 	DEBUG_PRINTF2(_L8("COmxILCallbackManager::RegisterTunnelCallback : aTunnelledComponentHandle [%x]"), aTunnelledComponentHandle);
       
   205 
       
   206 	CTunnelCallbackRegistrationCommand* pTunnelCBacksReg =
       
   207 		new CTunnelCallbackRegistrationCommand(aLocalPortIndex,
       
   208 											   aLocalPortDirection,
       
   209 											   aTunnelledComponentHandle,
       
   210 											   aTunnelledPortIndex);
       
   211 
       
   212 	if (!pTunnelCBacksReg || (iCommandQueue.Send(pTunnelCBacksReg) != KErrNone))
       
   213 		{
       
   214 		delete pTunnelCBacksReg;
       
   215 		return OMX_ErrorInsufficientResources;
       
   216 		}
       
   217 
       
   218 	return OMX_ErrorNone;
       
   219 
       
   220 	}
       
   221 
       
   222 EXPORT_C OMX_ERRORTYPE
       
   223 COmxILCallbackManager::DeregisterTunnelCallback(
       
   224 	OMX_U32 aLocalPortIndex)
       
   225 	{
       
   226 
       
   227 	DEBUG_PRINTF(_L8("COmxILCallbackManager::DeregisterTunnelCallback"));
       
   228 
       
   229 	return RegisterTunnelCallback(aLocalPortIndex,
       
   230 								  OMX_DirMax,
       
   231 								  0,
       
   232 								  0);
       
   233 
       
   234 	}
       
   235 
       
   236 EXPORT_C OMX_ERRORTYPE
       
   237 COmxILCallbackManager::RegisterBufferMarkPropagationPort(
       
   238 	OMX_U32 aPortIndex,
       
   239 	OMX_U32 aPropagationPortIndex)
       
   240 	{
       
   241 	DEBUG_PRINTF(_L8("COmxILCallbackManager::RegisterBufferMarkPropagationPort"));
       
   242 
       
   243 	CBufferMarkPropagationRegistrationCommand* pBufferMarkPropReg =
       
   244 		new CBufferMarkPropagationRegistrationCommand(aPortIndex,
       
   245 													  aPropagationPortIndex);
       
   246 	if (!pBufferMarkPropReg || (iCommandQueue.Send(pBufferMarkPropReg) != KErrNone))
       
   247 		{
       
   248 		delete pBufferMarkPropReg;
       
   249 		HandleInsufficientResources();
       
   250 		}
       
   251 
       
   252 	return OMX_ErrorNone;
       
   253 
       
   254 	}
       
   255 
       
   256 EXPORT_C TBool
       
   257 COmxILCallbackManager::BufferRemovalIndication(
       
   258 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   259 	OMX_DIRTYPE aDirection)
       
   260 	{
       
   261 	DEBUG_PRINTF(_L8("COmxILCallbackManager::BufferRemovalIndication"));
       
   262 
       
   263 	CBufferRemovalCommand* pBufferRemovalCmd =
       
   264 		new CBufferRemovalCommand(apBufferHeader, aDirection);
       
   265 
       
   266 	if (!pBufferRemovalCmd ||
       
   267 		(iCommandQueue.Send(pBufferRemovalCmd) != KErrNone))
       
   268 		{
       
   269 		delete pBufferRemovalCmd;
       
   270 		HandleInsufficientResources();
       
   271 		}
       
   272 
       
   273 	// Always return false now as the buffer would be removed asynchronously
       
   274 	return EFalse;
       
   275 
       
   276 	}
       
   277 
       
   278 EXPORT_C OMX_ERRORTYPE
       
   279 COmxILCallbackManager::TransitionCompleteNotification(OMX_STATETYPE aOmxState)
       
   280 	{
       
   281     DEBUG_PRINTF(_L8("COmxILCallbackManager::TransitionCompleteNotification"));
       
   282 
       
   283 	return EventNotificationImpl(OMX_EventCmdComplete,
       
   284 								OMX_CommandStateSet,
       
   285 								aOmxState,
       
   286 								0);
       
   287 
       
   288 	}
       
   289 
       
   290 
       
   291 EXPORT_C OMX_ERRORTYPE
       
   292 COmxILCallbackManager::CommandCompleteNotification(OMX_COMMANDTYPE aOmxCommand,
       
   293 												   OMX_U32 aOmxPortIndex)
       
   294 	{
       
   295     DEBUG_PRINTF(_L8("COmxILCallbackManager::CommandCompleteNotification"));
       
   296 
       
   297 	return EventNotification(OMX_EventCmdComplete,
       
   298 							 aOmxCommand,
       
   299 							 aOmxPortIndex,
       
   300 							 0);
       
   301 
       
   302 	}
       
   303 
       
   304 
       
   305 EXPORT_C OMX_ERRORTYPE
       
   306 COmxILCallbackManager::ErrorEventNotification(OMX_ERRORTYPE aOmxError)
       
   307 	{
       
   308     DEBUG_PRINTF2(_L8("COmxILCallbackManager::ErrorEventNotification : aOmxError[%X] "), aOmxError);
       
   309 
       
   310 	return EventNotification(OMX_EventError,
       
   311 							 aOmxError,
       
   312 							 0,
       
   313 							 0);
       
   314 
       
   315 	}
       
   316 
       
   317 EXPORT_C OMX_ERRORTYPE
       
   318 COmxILCallbackManager::EventNotification(OMX_EVENTTYPE aEvent,
       
   319 										 TUint32 aData1,
       
   320 										 TUint32 aData2,
       
   321 										 OMX_STRING aExtraInfo)
       
   322 	{
       
   323 	// The error code is ignored intentionally, as errors from this function cannot be handled by clients, since they don't have
       
   324 	// another mechanism for reporting an error
       
   325 	(void)EventNotificationImpl(aEvent, aData1, aData2, aExtraInfo);
       
   326 	return OMX_ErrorNone;
       
   327 	}	
       
   328 										 
       
   329 										 
       
   330 OMX_ERRORTYPE COmxILCallbackManager::EventNotificationImpl(OMX_EVENTTYPE aEvent,
       
   331 										 TUint32 aData1,
       
   332 										 TUint32 aData2,
       
   333 										 OMX_STRING aExtraInfo)										 
       
   334 	{
       
   335     DEBUG_PRINTF4(_L8("COmxILCallbackManager::EventNotificationImpl : aEvent[%X] aData1[%X] aData2[%u]"), aEvent, aData1, aData2);
       
   336 
       
   337 	CEventCallbackCommand* pEventCBack =
       
   338 		new CEventCallbackCommand(aEvent,
       
   339 								  aData1,
       
   340 								  aData2,
       
   341 								  aExtraInfo);
       
   342 	if (!pEventCBack || (iCommandQueue.Send(pEventCBack) != KErrNone))
       
   343 		{
       
   344 		delete pEventCBack;
       
   345 		HandleInsufficientResources();
       
   346 		return OMX_ErrorInsufficientResources;
       
   347 		}
       
   348 
       
   349 	return OMX_ErrorNone;
       
   350 
       
   351 	}
       
   352 
       
   353 
       
   354 EXPORT_C OMX_ERRORTYPE
       
   355 COmxILCallbackManager::BufferDoneNotification(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   356 											 OMX_U32 aLocalPortIndex,
       
   357 											 OMX_DIRTYPE aLocalPortDirection)
       
   358 	{
       
   359     DEBUG_PRINTF(_L8("COmxILCallbackManager::BufferDoneNotificaton"));
       
   360 
       
   361 	return SendBufferDoneNotification(apBufferHeader,
       
   362 									  aLocalPortIndex,
       
   363 									  aLocalPortDirection,
       
   364 									  CCallbackCommand::EPriorityNormal);
       
   365 
       
   366 	}
       
   367 
       
   368 EXPORT_C OMX_ERRORTYPE
       
   369 COmxILCallbackManager::ClockBufferDoneNotification(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   370 												   OMX_U32 aLocalPortIndex,
       
   371 												   OMX_DIRTYPE aLocalPortDirection)
       
   372 	{
       
   373     DEBUG_PRINTF(_L8("COmxILCallbackManager::ClockBufferDoneNotification"));
       
   374 
       
   375 	return SendBufferDoneNotification(apBufferHeader,
       
   376 									  aLocalPortIndex,
       
   377 									  aLocalPortDirection,
       
   378 									  CCallbackCommand::EPriorityHigh);
       
   379 
       
   380 	}
       
   381 
       
   382 EXPORT_C OMX_ERRORTYPE
       
   383 COmxILCallbackManager::PortSettingsChangeNotification(
       
   384 	OMX_U32 aLocalPortIndex,
       
   385 	TUint aPortSettingsIndex,
       
   386 	const TDesC8& aPortSettings)
       
   387 	{
       
   388     DEBUG_PRINTF2(_L8("COmxILCallbackManager::PortSettingsChangeNotification : aLocalPortIndex[%d]"), aLocalPortIndex);
       
   389 
       
   390 	HBufC8* pPortSettings = aPortSettings.Alloc();
       
   391 	if (!pPortSettings)
       
   392 		{
       
   393 		HandleInsufficientResources();
       
   394 		return OMX_ErrorNone;
       
   395 		}
       
   396 
       
   397 	CPortSettingsChangeCommand* pPortSettingsCmd =
       
   398 		new CPortSettingsChangeCommand(aLocalPortIndex,
       
   399 									   aPortSettingsIndex,
       
   400 									   pPortSettings);
       
   401 	if (!pPortSettingsCmd)
       
   402 		{
       
   403 		delete pPortSettings;
       
   404 		HandleInsufficientResources();
       
   405 		return OMX_ErrorNone;
       
   406 		}
       
   407 
       
   408 	if (iCommandQueue.Send(pPortSettingsCmd) != KErrNone)
       
   409 		{
       
   410 		delete pPortSettingsCmd; // Destructor will delete pPortSettings
       
   411 		HandleInsufficientResources();
       
   412 		}
       
   413 
       
   414 	return OMX_ErrorNone;
       
   415 
       
   416 	}
       
   417 
       
   418 OMX_ERRORTYPE
       
   419 COmxILCallbackManager::SendBufferDoneNotification(
       
   420 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   421 	OMX_U32 aLocalPortIndex,
       
   422 	OMX_DIRTYPE aLocalPortDirection,
       
   423 	TInt aPriority)
       
   424 	{
       
   425     DEBUG_PRINTF(_L8("COmxILCallbackManager::SendBufferDoneNotification"));
       
   426 
       
   427 	__ASSERT_ALWAYS(apBufferHeader &&
       
   428 					(OMX_DirInput == aLocalPortDirection ||
       
   429 					 OMX_DirOutput == aLocalPortDirection),
       
   430 					User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   431 
       
   432 	__ASSERT_ALWAYS(apBufferHeader->nOffset + apBufferHeader->nFilledLen
       
   433 					<= apBufferHeader->nAllocLen,
       
   434 					User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   435 
       
   436 	CBufferDoneCallbackCommand* pEventCBack =
       
   437 		new CBufferDoneCallbackCommand(apBufferHeader,
       
   438 									   aLocalPortIndex,
       
   439 									   aLocalPortDirection,
       
   440 									   aPriority);
       
   441 
       
   442 	if (!pEventCBack || (iCommandQueue.Send(pEventCBack) != KErrNone))
       
   443 		{
       
   444 		delete pEventCBack;
       
   445 		HandleInsufficientResources();
       
   446 		}
       
   447 
       
   448 	return OMX_ErrorNone;
       
   449 
       
   450 	}
       
   451 
       
   452 
       
   453 void
       
   454 COmxILCallbackManager::RunL()
       
   455 	{
       
   456     DEBUG_PRINTF2(_L8("COmxILCallbackManager::RunL : Handle[%X]"), ipHandle);
       
   457 
       
   458 	ProcessQueue(iCommandQueue);
       
   459 
       
   460 	// Setup for next callbacks
       
   461 	iCommandQueue.NotifyDataAvailable(iStatus);
       
   462 	SetActive();
       
   463 
       
   464 	}
       
   465 
       
   466 
       
   467 void
       
   468 COmxILCallbackManager::ProcessQueue(RCallbackManagerQueue& aQueue)
       
   469 	{
       
   470     DEBUG_PRINTF2(_L8("COmxILCallbackManager::ProcessQueue : Handle[%X]"), ipHandle);
       
   471 
       
   472 	CCallbackCommand* pCommand = 0;
       
   473 
       
   474 	TInt receiveRes = 0;
       
   475 	TBool hasBeenDeferred = EFalse;
       
   476 	while ((receiveRes = aQueue.Receive(pCommand)) == KErrNone)
       
   477 		{
       
   478 		if (pCommand)
       
   479 			{
       
   480 			DEBUG_PRINTF2(_L8("COmxILCallbackManager::ProcessQueue : aQueue.Receive [%X]"),
       
   481 						  pCommand);
       
   482 			hasBeenDeferred = EFalse;
       
   483 			(*pCommand)(*this, hasBeenDeferred);
       
   484 			if (hasBeenDeferred)
       
   485 				{
       
   486 				// Move the current command to the pending queue
       
   487 				if (iPendingQueue.Send(pCommand) != KErrNone)
       
   488 					{
       
   489 					delete pCommand;
       
   490 					pCommand = 0;
       
   491 					HandleInsufficientResources();
       
   492 					}
       
   493 				}
       
   494 			else
       
   495 				{
       
   496 				delete pCommand;
       
   497 				pCommand = 0;
       
   498 				}
       
   499 			}
       
   500 
       
   501 		}
       
   502 
       
   503 	if (KErrNoMemory == receiveRes)
       
   504 		{
       
   505 		HandleInsufficientResources();
       
   506 		}
       
   507 
       
   508 	}
       
   509 
       
   510 void
       
   511 COmxILCallbackManager::DoCancel()
       
   512 	{
       
   513     DEBUG_PRINTF2(_L8("COmxILCallbackManager::DoCancel : Handle[%X]"), ipHandle);
       
   514 
       
   515 	iCommandQueue.CancelDataAvailable();
       
   516 
       
   517 	}
       
   518 
       
   519 
       
   520 //
       
   521 // COmxILCallbackManager::RCallbackManagerQueue
       
   522 //
       
   523 TBool
       
   524 COmxILCallbackManager::RCallbackManagerQueue::RemoveBufferDoneCbCommandsByBufferHeader(
       
   525 	COmxILCallbackManager& aCbMgr,
       
   526 	const OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   527 	OMX_DIRTYPE aDirection)
       
   528 	{
       
   529     DEBUG_PRINTF2(_L8("RCallbackManagerQueue::RemoveBufferDoneCbCommandsByBufferHeader : Handle[%X]"), aCbMgr.ipHandle);
       
   530 
       
   531 	if (KErrNone != DrainBackQueue())
       
   532 		{
       
   533 		aCbMgr.HandleInsufficientResources();
       
   534 		return EFalse;
       
   535 		}
       
   536 
       
   537 	if(!iFrontQueue.IsEmpty())
       
   538 		{
       
   539 		TBool removed = EFalse;
       
   540 		TDblQueIter<TFrontQueueElement> frontQueueIter(iFrontQueue);
       
   541 		TFrontQueueElement* pLastElement = iFrontQueue.Last();
       
   542 		TFrontQueueElement* pCurrentElement = 0;
       
   543 
       
   544 		do
       
   545 			{
       
   546 			pCurrentElement = frontQueueIter++;
       
   547 			__ASSERT_DEBUG(pCurrentElement && pCurrentElement->ipInfo,
       
   548 						   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   549 			removed = reinterpret_cast<CCallbackCommand*>(
       
   550 				const_cast<TAny*>(pCurrentElement->ipInfo))->
       
   551 				DoRemoveBufferDoneCbCommandByBufferHeader(aCbMgr,
       
   552 														  apBufferHeader,
       
   553 														  aDirection);
       
   554 			if (removed)
       
   555 				{
       
   556 				pCurrentElement->iLink.Deque();
       
   557 				delete reinterpret_cast<CCallbackCommand*>(
       
   558 					const_cast<TAny*>(pCurrentElement->ipInfo));
       
   559 				delete pCurrentElement;
       
   560 				DEBUG_PRINTF2(_L8("RCallbackManagerQueue::RemoveBufferDoneCbCommandsByBufferHeader : Removed Buffer Done @ Header [%X]"), apBufferHeader);
       
   561 				return ETrue;
       
   562 				}
       
   563 			}
       
   564 		while (pCurrentElement != pLastElement);
       
   565 		}
       
   566 
       
   567 	return EFalse;
       
   568 
       
   569 	}
       
   570 
       
   571 TBool
       
   572 COmxILCallbackManager::RCallbackManagerQueue::RemoveBufferDoneCbCommandsByPortIndex(
       
   573 	COmxILCallbackManager& aCbMgr,
       
   574 	OMX_U32 aLocalPortIndex)
       
   575 	{
       
   576     DEBUG_PRINTF2(_L8("RCallbackManagerQueue::RemoveBufferDoneCbCommandsByPortIndex : Handle[%X]"), aCbMgr.ipHandle);
       
   577 
       
   578 	TBool somethingRemoved = EFalse;
       
   579 
       
   580 	if (KErrNone != DrainBackQueue())
       
   581 		{
       
   582 		aCbMgr.HandleInsufficientResources();
       
   583 		return EFalse;
       
   584 		}
       
   585 
       
   586 	if(!iFrontQueue.IsEmpty())
       
   587 		{
       
   588 		TBool removed = EFalse;
       
   589 		TDblQueIter<TFrontQueueElement> frontQueueIter(iFrontQueue);
       
   590 		TFrontQueueElement* pLastElement = iFrontQueue.Last();
       
   591 		TFrontQueueElement* pCurrentElement = 0;
       
   592 
       
   593 		do
       
   594 			{
       
   595 			pCurrentElement = frontQueueIter++;
       
   596 			__ASSERT_DEBUG(pCurrentElement && pCurrentElement->ipInfo,
       
   597 						   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   598 			removed = reinterpret_cast<CCallbackCommand*>(
       
   599 				const_cast<TAny*>(pCurrentElement->ipInfo))->
       
   600 				DoRemoveBufferDoneCbCommandByPortIndex(aCbMgr,
       
   601 													   aLocalPortIndex);
       
   602 			if (removed)
       
   603 				{
       
   604 				somethingRemoved = ETrue;
       
   605 				pCurrentElement->iLink.Deque();
       
   606 				delete reinterpret_cast<CCallbackCommand*>(
       
   607 					const_cast<TAny*>(pCurrentElement->ipInfo));
       
   608 				delete pCurrentElement;
       
   609 				DEBUG_PRINTF2(_L8("RCallbackManagerQueue::RemoveBufferDoneCbCommandsByPortIndex : Removed Buffer Done @ Port Index [%d]"), aLocalPortIndex);
       
   610 				}
       
   611 			}
       
   612 		while (pCurrentElement != pLastElement);
       
   613 		}
       
   614 
       
   615 	return somethingRemoved;
       
   616 
       
   617 	}
       
   618 
       
   619 
       
   620 TBool
       
   621 COmxILCallbackManager::RCallbackManagerQueue::ExecuteBufferDoneCbCommandsByPortIndex(
       
   622 	COmxILCallbackManager& aCbMgr,
       
   623 	OMX_U32 aLocalPortIndex)
       
   624 	{
       
   625     DEBUG_PRINTF2(_L8("RCallbackManagerQueue::ExecuteBufferDoneCbCommandsByPortIndex : Handle[%X]"), aCbMgr.ipHandle);
       
   626 
       
   627 	TBool somethingExecuted = EFalse;
       
   628 
       
   629 	if (KErrNone != DrainBackQueue())
       
   630 		{
       
   631 		aCbMgr.HandleInsufficientResources();
       
   632 		return EFalse;
       
   633 		}
       
   634 
       
   635 	if(!iFrontQueue.IsEmpty())
       
   636 		{
       
   637 		TBool executed = EFalse;
       
   638 		TDblQueIter<TFrontQueueElement> frontQueueIter(iFrontQueue);
       
   639 		TFrontQueueElement* pLastElement = iFrontQueue.Last();
       
   640 		TFrontQueueElement* pCurrentElement = 0;
       
   641 
       
   642 		do
       
   643 			{
       
   644 			pCurrentElement = frontQueueIter++;
       
   645 			__ASSERT_DEBUG(pCurrentElement && pCurrentElement->ipInfo,
       
   646 						   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   647 			executed = reinterpret_cast<CCallbackCommand*>(
       
   648 				const_cast<TAny*>(pCurrentElement->ipInfo))->
       
   649 				DoExecuteBufferDoneCbCommandByPortIndex(aCbMgr,
       
   650 														aLocalPortIndex);
       
   651 			if (executed)
       
   652 				{
       
   653 				somethingExecuted = ETrue;
       
   654 				pCurrentElement->iLink.Deque();
       
   655 				delete reinterpret_cast<CCallbackCommand*>(
       
   656 					const_cast<TAny*>(pCurrentElement->ipInfo));
       
   657 				delete pCurrentElement;
       
   658 				DEBUG_PRINTF2(_L8("RCallbackManagerQueue::ExecuteBufferDoneCbCommandsByPortIndex : Executed Buffer Done @ Port Index [%d]"), aLocalPortIndex);
       
   659 				}
       
   660 			}
       
   661 		while (pCurrentElement != pLastElement);
       
   662 		}
       
   663 
       
   664 	return somethingExecuted;
       
   665 
       
   666 	}
       
   667 
       
   668 
       
   669 //
       
   670 // COmxILCallbackManager commands
       
   671 //
       
   672 
       
   673 TBool
       
   674 COmxILCallbackManager::CCallbackCommand::DoRemoveBufferDoneCbCommandByBufferHeader(
       
   675 	COmxILCallbackManager& /*aCbMgr*/,
       
   676 	const OMX_BUFFERHEADERTYPE* /*apBufferHeader*/,
       
   677 	OMX_DIRTYPE /*aDirection*/)
       
   678 	{
       
   679 	return EFalse;
       
   680 	}
       
   681 
       
   682 TBool
       
   683 COmxILCallbackManager::CCallbackCommand::DoRemoveBufferDoneCbCommandByPortIndex(
       
   684 	COmxILCallbackManager& /*aCbMgr*/,
       
   685 	OMX_U32 /* aLocalPortIndex */)
       
   686 	{
       
   687 	return EFalse;
       
   688 	}
       
   689 
       
   690 TBool
       
   691 COmxILCallbackManager::CCallbackCommand::DoExecuteBufferDoneCbCommandByPortIndex(
       
   692 	COmxILCallbackManager& /*aCbMgr*/,
       
   693 	OMX_U32 /* aLocalPortIndex */)
       
   694 	{
       
   695 	return EFalse;
       
   696 	}
       
   697 
       
   698 void
       
   699 COmxILCallbackManager::CCompHandleRegistrationCommand::operator()(
       
   700 	COmxILCallbackManager& aCbMgr, TBool& /* aHasBeenDeferred */)
       
   701 	{
       
   702     DEBUG_PRINTF2(_L8("CCompHandleRegistrationCommand::operator() : Handle[%X]"), aCbMgr.ipHandle);
       
   703 	aCbMgr.DoRegisterComponentHandle(ipHandle);
       
   704 	}
       
   705 
       
   706 void
       
   707 COmxILCallbackManager::CClientCallbacksRegistrationCommand::operator()(
       
   708 	COmxILCallbackManager& aCbMgr, TBool& /* aHasBeenDeferred */)
       
   709 	{
       
   710     DEBUG_PRINTF2(_L8("CClientCallbacksRegistrationCommand::operator() : Handle[%X]"), aCbMgr.ipHandle);
       
   711 	aCbMgr.DoRegisterILClientCallbacks(ipCallbacks, ipAppData);
       
   712 	}
       
   713 
       
   714 void
       
   715 COmxILCallbackManager::CBufferMarkPropagationRegistrationCommand::operator()(
       
   716 	COmxILCallbackManager& aCbMgr, TBool& /* aHasBeenDeferred */)
       
   717 	{
       
   718     DEBUG_PRINTF2(_L8("CBufferMarkPropagationRegistrationCommand::operator() : Handle[%X]"), aCbMgr.ipHandle);
       
   719 
       
   720 	OMX_ERRORTYPE omxError =
       
   721 		aCbMgr.DoRegisterBufferMarkPropagationPort(
       
   722 			iMarkPropagationInfo.iPortIndex,
       
   723 			iMarkPropagationInfo.iPropagationPortIndex);
       
   724 
       
   725 	if (OMX_ErrorInsufficientResources == omxError)
       
   726 		{
       
   727 		aCbMgr.HandleInsufficientResources();
       
   728 		}
       
   729 	}
       
   730 
       
   731 void
       
   732 COmxILCallbackManager::CBufferRemovalCommand::operator()(
       
   733 	COmxILCallbackManager& aCbMgr, TBool& /* aHasBeenDeferred */)
       
   734 	{
       
   735     DEBUG_PRINTF2(_L8("CBufferRemovalCommand::operator() : Handle[%X]"), aCbMgr.ipHandle);
       
   736 
       
   737 	// Returned value not relevant
       
   738 	aCbMgr.iPendingQueue.RemoveBufferDoneCbCommandsByBufferHeader(
       
   739 		aCbMgr,
       
   740 		ipBufferHeader,
       
   741 		iDirection);
       
   742 
       
   743 	// Returned value not relevant
       
   744 	aCbMgr.iCommandQueue.RemoveBufferDoneCbCommandsByBufferHeader(
       
   745 		aCbMgr,
       
   746 		ipBufferHeader,
       
   747 		iDirection);
       
   748 
       
   749 
       
   750 	}
       
   751 
       
   752 void
       
   753 COmxILCallbackManager::CTunnelCallbackRegistrationCommand::operator()(
       
   754 	COmxILCallbackManager& aCbMgr, TBool& /* aHasBeenDeferred */)
       
   755 	{
       
   756     DEBUG_PRINTF2(_L8("CTunnelCallbackRegistrationCommand::operator() : Handle[%X]"), aCbMgr.ipHandle);
       
   757 
       
   758 	if (!iTunnelInfo.iTunnelledComponentHandle)
       
   759 		{
       
   760 		// This is a tunnel deregistration command, then remove any pending
       
   761 		// callbacks on that tunnel...
       
   762 		aCbMgr.iCommandQueue.RemoveBufferDoneCbCommandsByPortIndex(
       
   763 			aCbMgr,
       
   764 			iTunnelInfo.iLocalPortIndex);
       
   765 		}
       
   766 
       
   767 	OMX_ERRORTYPE omxError =
       
   768 		aCbMgr.DoRegisterTunnelCallback(iTunnelInfo.iLocalPortIndex,
       
   769 										iTunnelInfo.iLocalPortDirection,
       
   770 										iTunnelInfo.iTunnelledComponentHandle,
       
   771 										iTunnelInfo.iTunnelledPortIndex);
       
   772 
       
   773 	if (OMX_ErrorInsufficientResources == omxError)
       
   774 		{
       
   775 		aCbMgr.HandleInsufficientResources();
       
   776 		}
       
   777 
       
   778 	}
       
   779 
       
   780 
       
   781 void
       
   782 COmxILCallbackManager::CEventCallbackCommand::operator()(
       
   783 	COmxILCallbackManager& aCbMgr, TBool& /* aHasBeenDeferred */)
       
   784 	{
       
   785     DEBUG_PRINTF2(_L8("CEventCallbackCommand::operator() : Handle[%X]"), aCbMgr.ipHandle);
       
   786 
       
   787 	OMX_ERRORTYPE omxError = OMX_ErrorNone;
       
   788 	switch(iData1)
       
   789 		{
       
   790 	case OMX_CommandStateSet:
       
   791 		{
       
   792 		aCbMgr.iPreviousState = aCbMgr.iCurrentState;
       
   793 		aCbMgr.iCurrentState  = static_cast<OMX_STATETYPE>(iData2);
       
   794 
       
   795 		DEBUG_PRINTF4(_L8("CEventCallbackCommand::operator() : Handle[%X] iPreviousState[%d] -> iCurrentState[%d]"), aCbMgr.ipHandle, aCbMgr.iPreviousState, aCbMgr.iCurrentState);
       
   796 
       
   797 		if (OMX_StatePause == aCbMgr.iPreviousState &&
       
   798 			OMX_StateIdle == aCbMgr.iCurrentState)
       
   799 			{
       
   800 			// Flush pending queue first...
       
   801 			aCbMgr.ProcessQueue(aCbMgr.iPendingQueue);
       
   802 
       
   803 			// ... and now signal command completion...
       
   804 			omxError =
       
   805 				aCbMgr.DoEventNotification(iEvent,
       
   806 										   iData1,
       
   807 										   iData2,
       
   808 										   iExtraInfo);
       
   809 
       
   810 			}
       
   811 		else if (OMX_StatePause == aCbMgr.iPreviousState &&
       
   812 			OMX_StateExecuting == aCbMgr.iCurrentState)
       
   813 			{
       
   814 			// Signal command completion first...
       
   815 			omxError =
       
   816 				aCbMgr.DoEventNotification(iEvent,
       
   817 										   iData1,
       
   818 										   iData2,
       
   819 										   iExtraInfo);
       
   820 
       
   821 			// ... and now flush...
       
   822 			aCbMgr.ProcessQueue(aCbMgr.iPendingQueue);
       
   823 
       
   824 			}
       
   825 		else
       
   826 			{
       
   827 			// Signal command completion...
       
   828 			omxError =
       
   829 				aCbMgr.DoEventNotification(iEvent,
       
   830 										   iData1,
       
   831 										   iData2,
       
   832 										   iExtraInfo);
       
   833 
       
   834 			}
       
   835 
       
   836 		}
       
   837 		break;
       
   838 
       
   839 	case OMX_CommandPortDisable:
       
   840 	case OMX_CommandFlush:
       
   841 		{
       
   842 		// Process pending queue unconditionally...
       
   843 		aCbMgr.iFlushPendingQueue = ETrue;
       
   844 
       
   845 		// Flush first...
       
   846 		if (OMX_ALL == iData2)
       
   847 			{
       
   848 			aCbMgr.ProcessQueue(aCbMgr.iPendingQueue);
       
   849 			}
       
   850 		else
       
   851 			{
       
   852 			aCbMgr.iPendingQueue.
       
   853 				ExecuteBufferDoneCbCommandsByPortIndex(aCbMgr,
       
   854 													   iData2);
       
   855 
       
   856 			}
       
   857 
       
   858 		aCbMgr.iFlushPendingQueue = EFalse;
       
   859 
       
   860 		// ... and now signal command completion...
       
   861 		omxError =
       
   862 			aCbMgr.DoEventNotification(iEvent,
       
   863 									   iData1,
       
   864 									   iData2,
       
   865 									   iExtraInfo);
       
   866 
       
   867 		}
       
   868 		break;
       
   869 
       
   870 	default:
       
   871 		{
       
   872 		// Signal command completion...
       
   873 		omxError =
       
   874 			aCbMgr.DoEventNotification(iEvent,
       
   875 									   iData1,
       
   876 									   iData2,
       
   877 									   iExtraInfo);
       
   878 
       
   879 		}
       
   880 
       
   881 		};
       
   882 
       
   883 	if (OMX_ErrorInsufficientResources == omxError)
       
   884 		{
       
   885 		aCbMgr.HandleInsufficientResources();
       
   886 		}
       
   887 
       
   888 	}
       
   889 
       
   890 
       
   891 void
       
   892 COmxILCallbackManager::CBufferDoneCallbackCommand::operator()(
       
   893 	COmxILCallbackManager& aCbMgr, TBool& aHasBeenDeferred)
       
   894 	{
       
   895     DEBUG_PRINTF2(_L8("CBufferDoneCallbackCommand::operator() : Handle[%X]"), aCbMgr.ipHandle);
       
   896 
       
   897 	// Only send the buffer done callback if is not in Pause stae or if there
       
   898 	// is a buffer flushing situation...
       
   899 
       
   900 	if ((OMX_StatePause == aCbMgr.iCurrentState) &&
       
   901 		(!aCbMgr.iFlushPendingQueue))
       
   902 		{
       
   903 		aHasBeenDeferred = ETrue;
       
   904 		return;
       
   905 		}
       
   906 
       
   907 	OMX_ERRORTYPE omxError =
       
   908 		aCbMgr.DoBufferDoneNotification(ipBufferHeader,
       
   909 										iLocalPortIndex,
       
   910 										iLocalPortDirection);
       
   911 
       
   912 	if (OMX_ErrorInsufficientResources == omxError)
       
   913 		{
       
   914 		aCbMgr.HandleInsufficientResources();
       
   915 		}
       
   916 
       
   917 	}
       
   918 
       
   919 TBool
       
   920 COmxILCallbackManager::CBufferDoneCallbackCommand::DoRemoveBufferDoneCbCommandByBufferHeader(
       
   921 	COmxILCallbackManager& aCbMgr,
       
   922 	const OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   923 	OMX_DIRTYPE aDirection)
       
   924 	{
       
   925 
       
   926 	if (apBufferHeader == ipBufferHeader)
       
   927 		{
       
   928 		__ASSERT_DEBUG(aCbMgr.ipFsm,
       
   929 					   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   930 		__ASSERT_DEBUG(aDirection == OMX_DirInput ||
       
   931 					   aDirection == OMX_DirOutput,
       
   932 					   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   933 
       
   934 		DEBUG_PRINTF4(_L8("DoRemoveBufferDoneCbCommandByBufferHeader() : Nofiying FSM : Handle[%X] aDirection[%X] apBufferHeader[%X]"), aCbMgr.ipHandle, aDirection, apBufferHeader);
       
   935 
       
   936 		// Make sure the buffer contents are cleared...
       
   937 		TOmxILUtil::ClearBufferContents(
       
   938 			const_cast<OMX_BUFFERHEADERTYPE*>(apBufferHeader));
       
   939 
       
   940 		if (aDirection == OMX_DirInput)
       
   941 			{
       
   942 			aCbMgr.ipFsm->EmptyThisBuffer(
       
   943 				const_cast<OMX_BUFFERHEADERTYPE*>(apBufferHeader));
       
   944 			}
       
   945 		else
       
   946 			{
       
   947 			aCbMgr.ipFsm->FillThisBuffer(
       
   948 				const_cast<OMX_BUFFERHEADERTYPE*>(apBufferHeader));
       
   949 			}
       
   950 		return ETrue;
       
   951 		}
       
   952 
       
   953 	return EFalse;
       
   954 
       
   955 	}
       
   956 
       
   957 //
       
   958 // This method only prints some logging information for debugging purposes. For
       
   959 // now, there's no other action to be performed as the deletion is done by the caller.
       
   960 //
       
   961 TBool
       
   962 COmxILCallbackManager::CBufferDoneCallbackCommand::DoRemoveBufferDoneCbCommandByPortIndex(
       
   963 	COmxILCallbackManager& /* aCbMgr */,
       
   964 	OMX_U32 aLocalPortIndex)
       
   965 	{
       
   966 
       
   967 	if (iLocalPortIndex == aLocalPortIndex)
       
   968 		{
       
   969 		DEBUG_PRINTF2(_L8("CBufferDoneCallbackCommand::DoRemoveBufferDoneCbCommandByPortIndex() : FOUND -> PortIndex[%d]"), aLocalPortIndex);
       
   970 		return ETrue;
       
   971 		}
       
   972 
       
   973     DEBUG_PRINTF2(_L8("CBufferDoneCallbackCommand::DoRemoveBufferDoneCbCommandByPortIndex() : NOT FOUND -> PortIndex[%d]"), aLocalPortIndex);
       
   974 
       
   975 	return EFalse;
       
   976 	}
       
   977 
       
   978 
       
   979 TBool
       
   980 COmxILCallbackManager::CBufferDoneCallbackCommand::DoExecuteBufferDoneCbCommandByPortIndex(
       
   981 	COmxILCallbackManager& aCbMgr,
       
   982 	OMX_U32 aLocalPortIndex)
       
   983 	{
       
   984 
       
   985 	TBool executed = EFalse;
       
   986 
       
   987 	if (iLocalPortIndex == aLocalPortIndex)
       
   988 		{
       
   989 		TBool hasBeenDeferred = EFalse;
       
   990 		// The only use case for this method is during unconditional flushing
       
   991 		// of the pending queue...
       
   992 		__ASSERT_DEBUG(aCbMgr.iFlushPendingQueue,
       
   993 					   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   994 		this->operator()(aCbMgr, hasBeenDeferred);
       
   995 		__ASSERT_DEBUG(!hasBeenDeferred,
       
   996 					   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   997 		executed = ETrue;
       
   998 		}
       
   999 
       
  1000 	DEBUG_PRINTF3(_L8("CBufferDoneCallbackCommand::DoExecuteBufferDoneCbCommandByPortIndex() : %s FOUND  -> PortIndex[%d]"),
       
  1001 				  (executed ? "" : "NOT"), aLocalPortIndex);
       
  1002 
       
  1003 	return executed;
       
  1004 
       
  1005 	}
       
  1006 
       
  1007 
       
  1008 TBool
       
  1009 XOmxILCallbackManagerIfImpl::TBufferMarkPropagationInfo::Compare(
       
  1010 	const TBufferMarkPropagationInfo& aBmpi1,
       
  1011 	const TBufferMarkPropagationInfo& aBmpi2)
       
  1012 	{
       
  1013 	return (aBmpi1.iPortIndex == aBmpi2.iPortIndex ? ETrue : EFalse);
       
  1014 	}
       
  1015 
       
  1016 TBool
       
  1017 XOmxILCallbackManagerIfImpl::TOutputPortBufferMarkInfo::Compare(
       
  1018 	const TOutputPortBufferMarkInfo& aOpbmi1,
       
  1019 	const TOutputPortBufferMarkInfo& aOpbmi2)
       
  1020 	{
       
  1021 	return (aOpbmi1.iPortIndex == aOpbmi2.iPortIndex ? ETrue : EFalse);
       
  1022 	}
       
  1023 
       
  1024 COmxILCallbackManager::CPortSettingsChangeCommand::~CPortSettingsChangeCommand()
       
  1025 	{
       
  1026 	delete ipPortSettings;
       
  1027 	}
       
  1028 
       
  1029 void
       
  1030 COmxILCallbackManager::CPortSettingsChangeCommand::operator()(
       
  1031 	COmxILCallbackManager& aCbMgr, TBool& /* aHasBeenDeferred */)
       
  1032 	{
       
  1033     DEBUG_PRINTF3(_L8("CPortSettingsChangeCommand::operator() : Handle[%X], iLocalPortIndex=[%d]"),
       
  1034 				  aCbMgr.ipHandle, iLocalPortIndex);
       
  1035 
       
  1036 	OMX_ERRORTYPE omxError =
       
  1037 		aCbMgr.DoPortSettingsChangeNotification(iLocalPortIndex,
       
  1038 												iPortSettingsIndex,
       
  1039 												*ipPortSettings);
       
  1040 
       
  1041 	if (OMX_ErrorInsufficientResources == omxError)
       
  1042 		{
       
  1043 		aCbMgr.HandleInsufficientResources();
       
  1044 		}
       
  1045 
       
  1046 	}