omxil/omxilcomponentcommon/src/common/omxilincontextcallbackmanager.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 "log.h"
       
    23 #include "omxilincontextcallbackmanager.h"
       
    24 #include "omxilfsm.h"
       
    25 #include "omxilutil.h"
       
    26 
       
    27 EXPORT_C COmxILInContextCallbackManager*
       
    28 COmxILInContextCallbackManager::NewL(
       
    29 	OMX_HANDLETYPE apComponentHandle,
       
    30 	OMX_PTR apAppData,
       
    31 	OMX_CALLBACKTYPE* apCallbacks)
       
    32 	{
       
    33     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::NewL"));
       
    34 	COmxILInContextCallbackManager* self = new (ELeave)COmxILInContextCallbackManager(
       
    35 		apComponentHandle,
       
    36 		apAppData,
       
    37 		apCallbacks);
       
    38 	CleanupStack::PushL(self);
       
    39 	self->ConstructL();
       
    40 	CleanupStack::Pop(self);
       
    41 	return self;
       
    42 	}
       
    43 
       
    44 void
       
    45 COmxILInContextCallbackManager::ConstructL()
       
    46 	{
       
    47     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::ConstructL"));
       
    48 
       
    49 	User::LeaveIfError(iLock.CreateLocal());
       
    50 
       
    51 	}
       
    52 
       
    53 COmxILInContextCallbackManager::COmxILInContextCallbackManager(OMX_HANDLETYPE apComponentHandle,
       
    54 											 OMX_PTR apAppData,
       
    55 											 OMX_CALLBACKTYPE* apCallbacks)
       
    56 	:
       
    57 	CBase(),
       
    58 	XOmxILCallbackManagerIfImpl(
       
    59 		static_cast<OMX_COMPONENTTYPE*>(apComponentHandle),
       
    60 		apAppData,
       
    61 		apCallbacks),
       
    62 	iLock(),
       
    63 	iPendingQueue(),
       
    64 	iFlushPendingQueue(EFalse),
       
    65 	iCurrentState(OMX_StateLoaded),
       
    66 	iPreviousState(OMX_StateLoaded)
       
    67 	{
       
    68     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::COmxILInContextCallbackManager"));
       
    69 	}
       
    70 
       
    71 EXPORT_C
       
    72 COmxILInContextCallbackManager::~COmxILInContextCallbackManager()
       
    73 	{
       
    74     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::~COmxILInContextCallbackManager Pending Queue count [%d]"),
       
    75 				  iPendingQueue.Count());
       
    76 
       
    77 	iLock.Close();
       
    78 
       
    79 	iPendingQueue.Close();
       
    80 
       
    81 	}
       
    82 
       
    83 void
       
    84 COmxILInContextCallbackManager::LockCallbackManager()
       
    85 	{
       
    86 	iLock.Wait();
       
    87 	}
       
    88 
       
    89 void
       
    90 COmxILInContextCallbackManager::UnlockCallbackManager()
       
    91 	{
       
    92 	iLock.Signal();
       
    93 	}
       
    94 
       
    95 EXPORT_C void
       
    96 COmxILInContextCallbackManager::SetPortManager(COmxILPortManager& apPortManager)
       
    97 	{
       
    98 	LockCallbackManager();
       
    99 	DoSetPortManager(apPortManager);
       
   100 	UnlockCallbackManager();
       
   101 	}
       
   102 
       
   103 EXPORT_C void
       
   104 COmxILInContextCallbackManager::SetFsm(COmxILFsm& apFsm)
       
   105 	{
       
   106 	LockCallbackManager();
       
   107 	DoSetFsm(apFsm);
       
   108 	UnlockCallbackManager();
       
   109 	}
       
   110 
       
   111 EXPORT_C OMX_ERRORTYPE
       
   112 COmxILInContextCallbackManager::RegisterComponentHandle(OMX_HANDLETYPE aComponentHandle)
       
   113 	{
       
   114     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::RegisterComponentHandle"));
       
   115 	LockCallbackManager();
       
   116 	OMX_ERRORTYPE omxError = DoRegisterComponentHandle(aComponentHandle);
       
   117 	UnlockCallbackManager();
       
   118 	return omxError;
       
   119 	}
       
   120 
       
   121 /**
       
   122    The IL Client callback registration is handled in this implementation
       
   123    asynchronously. Note that this implementation assumes that the IL Client
       
   124    will update the callbacks information once all expected callbacks from this
       
   125    component have already been received and therefore, the callback change will
       
   126    be safe leading to no race condition at the IL Client side.
       
   127 
       
   128    @param apCallbacks The IL Client callback structure.
       
   129 
       
   130    @param apAppData Pointer to an application provided value so that the
       
   131 	    application can have a component specific context when receiving
       
   132 	    the callback.
       
   133 
       
   134    @return OMX_ERRORTYPE
       
   135  */
       
   136 EXPORT_C OMX_ERRORTYPE
       
   137 COmxILInContextCallbackManager::RegisterILClientCallbacks(const OMX_CALLBACKTYPE* apCallbacks,
       
   138 												 const OMX_PTR apAppData)
       
   139 	{
       
   140     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::RegisterILClientCallbacks"));
       
   141 
       
   142 	LockCallbackManager();
       
   143 	OMX_ERRORTYPE omxError = DoRegisterILClientCallbacks(apCallbacks, apAppData);
       
   144 	UnlockCallbackManager();
       
   145 	return omxError;
       
   146 
       
   147 	}
       
   148 
       
   149 EXPORT_C OMX_ERRORTYPE
       
   150 COmxILInContextCallbackManager::RegisterTunnelCallback(
       
   151 	OMX_U32 aLocalPortIndex,
       
   152 	OMX_DIRTYPE aLocalPortDirection,
       
   153 	OMX_HANDLETYPE aTunnelledComponentHandle,
       
   154 	OMX_U32 aTunnelledPortIndex)
       
   155 	{
       
   156 	DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::RegisterTunnelCallback : aTunnelledComponentHandle [%x]"), aTunnelledComponentHandle);
       
   157 
       
   158 	LockCallbackManager();
       
   159 	OMX_ERRORTYPE omxError = DoRegisterTunnelCallback(aLocalPortIndex,
       
   160 													  aLocalPortDirection,
       
   161 													  aTunnelledComponentHandle,
       
   162 													  aTunnelledPortIndex);
       
   163 	UnlockCallbackManager();
       
   164 	return omxError;
       
   165 
       
   166 	}
       
   167 
       
   168 EXPORT_C OMX_ERRORTYPE
       
   169 COmxILInContextCallbackManager::DeregisterTunnelCallback(
       
   170 	OMX_U32 aLocalPortIndex)
       
   171 	{
       
   172 
       
   173 	DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::DeregisterTunnelCallback"));
       
   174 
       
   175 	LockCallbackManager();
       
   176 	OMX_ERRORTYPE omxError =  DoRegisterTunnelCallback(aLocalPortIndex,
       
   177 													   OMX_DirMax,
       
   178 													   0,
       
   179 													   0);
       
   180 	UnlockCallbackManager();
       
   181 	return omxError;
       
   182 
       
   183 	}
       
   184 
       
   185 EXPORT_C OMX_ERRORTYPE
       
   186 COmxILInContextCallbackManager::RegisterBufferMarkPropagationPort(
       
   187 	OMX_U32 aPortIndex,
       
   188 	OMX_U32 aPropagationPortIndex)
       
   189 	{
       
   190 	DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::RegisterBufferMarkPropagationPort"));
       
   191 
       
   192 	LockCallbackManager();
       
   193 	OMX_ERRORTYPE omxError = DoRegisterBufferMarkPropagationPort(
       
   194 		aPortIndex,
       
   195 		aPropagationPortIndex);
       
   196 	UnlockCallbackManager();
       
   197 	return omxError;
       
   198 
       
   199 	}
       
   200 
       
   201 EXPORT_C TBool
       
   202 COmxILInContextCallbackManager::BufferRemovalIndication(
       
   203 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   204 	OMX_DIRTYPE aDirection)
       
   205 	{
       
   206 	DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::BufferRemovalIndication"));
       
   207 
       
   208 	return RemoveBuffersByBufferHeader(
       
   209 		iPendingQueue, apBufferHeader, aDirection);
       
   210 
       
   211 	}
       
   212 
       
   213 EXPORT_C OMX_ERRORTYPE
       
   214 COmxILInContextCallbackManager::TransitionCompleteNotification(OMX_STATETYPE aOmxState)
       
   215 	{
       
   216     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::TransitionCompleteNotification"));
       
   217 
       
   218 	// No need to lock callback manager. Anyway, we should not have it locked
       
   219 	// when calling an IL Client callback method
       
   220 	OMX_ERRORTYPE omxError = EventNotification(OMX_EventCmdComplete,
       
   221 											   OMX_CommandStateSet,
       
   222 											   aOmxState,
       
   223 											   0);
       
   224 
       
   225 	return omxError;
       
   226 
       
   227 	}
       
   228 
       
   229 
       
   230 EXPORT_C OMX_ERRORTYPE
       
   231 COmxILInContextCallbackManager::CommandCompleteNotification(OMX_COMMANDTYPE aOmxCommand,
       
   232 												   OMX_U32 aOmxPortIndex)
       
   233 	{
       
   234     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::CommandCompleteNotification"));
       
   235 
       
   236 	// No need to lock callback manager. Anyway, we should not have it locked
       
   237 	// when calling an IL Client callback method
       
   238 
       
   239 	OMX_ERRORTYPE omxError = EventNotification(OMX_EventCmdComplete,
       
   240 											   aOmxCommand,
       
   241 											   aOmxPortIndex,
       
   242 											   0);
       
   243 
       
   244 	return omxError;
       
   245 
       
   246 	}
       
   247 
       
   248 
       
   249 EXPORT_C OMX_ERRORTYPE
       
   250 COmxILInContextCallbackManager::ErrorEventNotification(OMX_ERRORTYPE aOmxError)
       
   251 	{
       
   252     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::ErrorEventNotification : aOmxError[%X] "), aOmxError);
       
   253 
       
   254 	// No need to lock callback manager. Anyway, we should not have it locked
       
   255 	// when calling an IL Client callback method
       
   256 	OMX_ERRORTYPE omxError = EventNotification(OMX_EventError,
       
   257 											   aOmxError,
       
   258 											   0,
       
   259 											   0);
       
   260 
       
   261 	return omxError;
       
   262 
       
   263 	}
       
   264 
       
   265 EXPORT_C OMX_ERRORTYPE
       
   266 COmxILInContextCallbackManager::EventNotification(OMX_EVENTTYPE aEvent,
       
   267 												  TUint32 aData1,
       
   268 												  TUint32 aData2,
       
   269 												  OMX_STRING aExtraInfo)
       
   270 	{
       
   271     DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::EventNotification : aEvent[%u] aData1[%u] aData2[%u]"),
       
   272 				  aEvent, aData1, aData2);
       
   273 
       
   274 	OMX_ERRORTYPE omxError = OMX_ErrorNone;
       
   275 	switch(aData1)
       
   276 		{
       
   277 	case OMX_CommandStateSet:
       
   278 		{
       
   279 		LockCallbackManager();
       
   280 		iPreviousState = iCurrentState;
       
   281 		iCurrentState  = static_cast<OMX_STATETYPE>(aData2);
       
   282 
       
   283 		DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::EventNotification() : Handle[%X] iPreviousState[%d] -> iCurrentState[%d]"), ipHandle, iPreviousState, iCurrentState);
       
   284 
       
   285 		if (OMX_StatePause == iPreviousState &&
       
   286 			OMX_StateIdle == iCurrentState)
       
   287 			{
       
   288 			// Release lock before any callback gets called...
       
   289 			UnlockCallbackManager();
       
   290 
       
   291 			// Flush pending queue first...
       
   292 			FlushQueue(iPendingQueue);
       
   293 
       
   294 			// ... and now signal command completion...
       
   295 			omxError =
       
   296 				DoEventNotification(aEvent,
       
   297 									aData1,
       
   298 									aData2,
       
   299 									aExtraInfo);
       
   300 
       
   301 			}
       
   302 		else if (OMX_StatePause == iPreviousState &&
       
   303 				 OMX_StateExecuting == iCurrentState)
       
   304 			{
       
   305 			// Release lock before any callback...
       
   306 			UnlockCallbackManager();
       
   307 
       
   308 			// Signal command completion first...
       
   309 			omxError =
       
   310 				DoEventNotification(aEvent,
       
   311 									aData1,
       
   312 									aData2,
       
   313 									aExtraInfo);
       
   314 
       
   315 			// ... and now flush...
       
   316 			FlushQueue(iPendingQueue);
       
   317 
       
   318 			}
       
   319 		else
       
   320 			{
       
   321 			// Release lock before any callback...
       
   322 			UnlockCallbackManager();
       
   323 
       
   324 			// Signal command completion...
       
   325 			omxError =
       
   326 				DoEventNotification(aEvent,
       
   327 									aData1,
       
   328 									aData2,
       
   329 									aExtraInfo);
       
   330 
       
   331 			}
       
   332 
       
   333 		}
       
   334 		break;
       
   335 
       
   336 	case OMX_CommandPortDisable:
       
   337 	case OMX_CommandFlush:
       
   338 		{
       
   339 		// Flush first...
       
   340 		if (OMX_ALL == aData2)
       
   341 			{
       
   342 			FlushQueue(iPendingQueue);
       
   343 			}
       
   344 		else
       
   345 			{
       
   346 			FlushBuffersByPortIndex(iPendingQueue,
       
   347 									aData2);
       
   348 			}
       
   349 
       
   350 		// ... and now signal command completion...
       
   351 		omxError =
       
   352 			DoEventNotification(aEvent,
       
   353 								aData1,
       
   354 								aData2,
       
   355 								aExtraInfo);
       
   356 
       
   357 		}
       
   358 		break;
       
   359 
       
   360 	default:
       
   361 		{
       
   362 		// Signal command completion...
       
   363 		omxError =
       
   364 			DoEventNotification(aEvent,
       
   365 								aData1,
       
   366 								aData2,
       
   367 								aExtraInfo);
       
   368 
       
   369 		}
       
   370 
       
   371 		};
       
   372 
       
   373 	if (OMX_ErrorInsufficientResources == omxError)
       
   374 		{
       
   375 		HandleInsufficientResources();
       
   376 		}
       
   377 
       
   378 	return omxError;
       
   379 
       
   380 	}
       
   381 
       
   382 
       
   383 EXPORT_C OMX_ERRORTYPE
       
   384 COmxILInContextCallbackManager::BufferDoneNotification(
       
   385 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   386 	OMX_U32 aLocalPortIndex,
       
   387 	OMX_DIRTYPE aLocalPortDirection)
       
   388 	{
       
   389     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::BufferDoneNotificaton : BUFFER [%X]"),
       
   390 				  apBufferHeader);
       
   391 
       
   392 	__ASSERT_ALWAYS(apBufferHeader &&
       
   393 					(OMX_DirInput == aLocalPortDirection ||
       
   394 					 OMX_DirOutput == aLocalPortDirection),
       
   395 					User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   396 
       
   397 	__ASSERT_ALWAYS(apBufferHeader->nOffset + apBufferHeader->nFilledLen
       
   398 					<= apBufferHeader->nAllocLen,
       
   399 					User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   400 
       
   401 	__ASSERT_DEBUG(ipHandle && ipCallbacks,
       
   402 				   User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   403 
       
   404 	LockCallbackManager();
       
   405 	if (OMX_StatePause == iCurrentState)
       
   406 		{
       
   407 		if (KErrNone != iPendingQueue.Append(TOmxILBuffer(
       
   408 												 apBufferHeader,
       
   409 												 aLocalPortIndex,
       
   410 												 aLocalPortDirection)))
       
   411 			{
       
   412 			// Not much we can do here...
       
   413 			UnlockCallbackManager();
       
   414 			HandleInsufficientResources();
       
   415 			}
       
   416 		else
       
   417 			{
       
   418 			DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::BufferDoneNotificaton : DEFERRED buffer header[%X] port [%X] queue items [%d]"),
       
   419 					  apBufferHeader, aLocalPortIndex, iPendingQueue.Count());
       
   420 			UnlockCallbackManager();
       
   421 			}
       
   422 
       
   423 		return OMX_ErrorNone;
       
   424 
       
   425 		}
       
   426 	UnlockCallbackManager();
       
   427 
       
   428 	ProcessBufferDoneNotification(apBufferHeader,
       
   429 								  aLocalPortIndex,
       
   430 								  aLocalPortDirection);
       
   431 
       
   432 	return OMX_ErrorNone;
       
   433 
       
   434 	}
       
   435 
       
   436 void
       
   437 COmxILInContextCallbackManager::ProcessBufferDoneNotification(
       
   438 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   439 	OMX_U32 aLocalPortIndex,
       
   440 	OMX_DIRTYPE aLocalPortDirection)
       
   441 	{
       
   442     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::ProcessBufferDoneNotification : BUFFER [%X]"),
       
   443 				  apBufferHeader);
       
   444 
       
   445 	// Look for buffer marks to be signalled or propagated (maintain callback
       
   446 	// manager unlocked here)
       
   447 	SignalOrPropagateBufferMarks(apBufferHeader,
       
   448 								 aLocalPortDirection);
       
   449 
       
   450 	LockCallbackManager();
       
   451 
       
   452 	// find out whether the port is tunnelled or not
       
   453 	TBool tunnelled = EFalse;
       
   454 	OMX_COMPONENTTYPE* pTunnelledComponent = 0;
       
   455 	const TUint tunnelCount = iRegisteredTunnels.Count();
       
   456 	for (TUint i=0; i<tunnelCount; ++i)
       
   457 		{
       
   458 		if (iRegisteredTunnels[i].iLocalPortIndex ==
       
   459 			aLocalPortIndex)
       
   460 			{
       
   461 			tunnelled = ETrue;
       
   462 			pTunnelledComponent =
       
   463 				static_cast<OMX_COMPONENTTYPE*>(
       
   464 					iRegisteredTunnels[i].
       
   465 					iTunnelledComponentHandle);
       
   466 
       
   467 			__ASSERT_DEBUG(pTunnelledComponent,
       
   468 						   User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   469 
       
   470 			break;
       
   471 			}
       
   472 		}
       
   473 
       
   474 	// Unlock callback manager before calling the callback
       
   475 	UnlockCallbackManager();
       
   476 
       
   477 	if (tunnelled)
       
   478 		{
       
   479 		// From OMX_Core.h "Callbacks should not return an error to the
       
   480 		// component, so if an error occurs, the application shall handle it
       
   481 		// internally". Callback return error ignored here.
       
   482 		if (OMX_DirInput == aLocalPortDirection)
       
   483 			{
       
   484 			OMX_FillThisBuffer(pTunnelledComponent, apBufferHeader);
       
   485 			}
       
   486 		else
       
   487 			{
       
   488 			OMX_EmptyThisBuffer(pTunnelledComponent, apBufferHeader);
       
   489 			}
       
   490 
       
   491 		}
       
   492 	else
       
   493 		{
       
   494 		OMX_ERRORTYPE (*fp2CBackHandler)
       
   495 			(OMX_HANDLETYPE, OMX_PTR, OMX_BUFFERHEADERTYPE*) =
       
   496 			(aLocalPortDirection == OMX_DirInput ?
       
   497 			 ipCallbacks->EmptyBufferDone :
       
   498 			 ipCallbacks->FillBufferDone);
       
   499 
       
   500 
       
   501 		// From OMX_Core.h "Callbacks should not return an error to the
       
   502 		// component, so if an error occurs, the application shall handle it
       
   503 		// internally". Callback return error ignored here.
       
   504 		fp2CBackHandler(ipHandle,
       
   505 						ipAppData,
       
   506 						apBufferHeader);
       
   507 
       
   508 		}
       
   509 
       
   510 	}
       
   511 
       
   512 void
       
   513 COmxILInContextCallbackManager::SignalOrPropagateBufferMarks(
       
   514 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   515 	OMX_U32 aLocalPortIndex)
       
   516 	{
       
   517     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::SignalOrPropagateBufferMarks() : BUFFER [%X]"),
       
   518 				  apBufferHeader);
       
   519 
       
   520 	// Look for buffer marks to be signalled or propagated
       
   521 	if (apBufferHeader->hMarkTargetComponent)
       
   522 		{
       
   523 		// See if this component is the buffer mark target component...
       
   524 		if (apBufferHeader->hMarkTargetComponent == ipHandle)
       
   525 			{
       
   526 			// Inform the IL Client that a marked buffer has been processed...
       
   527 			ipCallbacks->EventHandler(ipHandle,
       
   528 									  ipAppData,
       
   529 									  OMX_EventMark,
       
   530 									  0,
       
   531 									  0,
       
   532 									  apBufferHeader->pMarkData);
       
   533 
       
   534 			// At this point, the mark has been delivered to the IL
       
   535 			// Client...Remove the mark from the processed header...
       
   536 			apBufferHeader->hMarkTargetComponent = 0;
       
   537 			apBufferHeader->pMarkData = 0;
       
   538 
       
   539 			}
       
   540 		else
       
   541 			{
       
   542 			// Propagate the mark...
       
   543 
       
   544 			LockCallbackManager();
       
   545 
       
   546 			// First find the buffer mark propagation port...
       
   547 			const TInt index = iBufferMarkPropagationPorts.Find(
       
   548 				TBufferMarkPropagationInfo(aLocalPortIndex),
       
   549 				TIdentityRelation<TBufferMarkPropagationInfo>(
       
   550 					&TBufferMarkPropagationInfo::Compare));
       
   551 
       
   552 			// Note that sink components don't propagate marks...
       
   553 			if (index != KErrNotFound)
       
   554 				{
       
   555 				const TBufferMarkPropagationInfo& propInfo =
       
   556 					iBufferMarkPropagationPorts[index];
       
   557 
       
   558 				// Let's check for the special case: The case for a source
       
   559 				// component where the output port is both the port that marks
       
   560 				// the headers and the port that propagates them ... Therefore
       
   561 				// no need to store the mark for later propagation...
       
   562 				if (propInfo.iPropagationPortIndex != aLocalPortIndex)
       
   563 					{
       
   564 					// Now, store temporarily the mark so the next time we send
       
   565 					// a buffer done callback in that propagation port, we mark
       
   566 					// that header accordingly...
       
   567 					// Unsuccessful insertion is ignored.
       
   568 					iBufferMarks.Append(
       
   569 						TOutputPortBufferMarkInfo(
       
   570 							propInfo.iPropagationPortIndex,
       
   571 							apBufferHeader->hMarkTargetComponent,
       
   572 							apBufferHeader->pMarkData));
       
   573 
       
   574 					// At this point the mark has been set for propagation to
       
   575 					// an output port. Remove the mark from the processed
       
   576 					// header...
       
   577 					apBufferHeader->hMarkTargetComponent = 0;
       
   578 					apBufferHeader->pMarkData = 0;
       
   579 					}
       
   580 				}
       
   581 
       
   582 			UnlockCallbackManager();
       
   583 
       
   584 			}
       
   585 		}
       
   586 	else
       
   587 		{
       
   588 		LockCallbackManager();
       
   589 
       
   590 		if(iBufferMarks.Count() != 0)
       
   591 			{
       
   592 			// Let's see if we have a mark waiting to go out...This will find the
       
   593 			// first mark in the local list of marks ...
       
   594 			const TInt index = iBufferMarks.Find(
       
   595 				TOutputPortBufferMarkInfo(aLocalPortIndex),
       
   596 				TIdentityRelation<TOutputPortBufferMarkInfo>(
       
   597 					&TOutputPortBufferMarkInfo::Compare));
       
   598 			if (index != KErrNotFound)
       
   599 				{
       
   600 				const TOutputPortBufferMarkInfo& markInfo =
       
   601 					iBufferMarks[index];
       
   602 
       
   603 				// Mark the header...
       
   604 				apBufferHeader->hMarkTargetComponent = markInfo.ipMarkTargetComponent;
       
   605 				apBufferHeader->pMarkData			 = markInfo.ipMarkData;
       
   606 
       
   607 				// Remove the mark info from the local store
       
   608 				iBufferMarks.Remove(index);
       
   609 				}
       
   610 
       
   611 			}
       
   612 
       
   613 		UnlockCallbackManager();
       
   614 
       
   615 		}
       
   616 
       
   617 
       
   618 	}
       
   619 
       
   620 EXPORT_C OMX_ERRORTYPE
       
   621 COmxILInContextCallbackManager::ClockBufferDoneNotification(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   622 											 OMX_U32 aLocalPortIndex,
       
   623 											 OMX_DIRTYPE aLocalPortDirection)
       
   624 	{
       
   625     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::ClockBufferDoneNotification"));
       
   626 
       
   627 	return BufferDoneNotification(apBufferHeader,
       
   628 								  aLocalPortIndex,
       
   629 								  aLocalPortDirection);
       
   630 
       
   631 	}
       
   632 
       
   633 EXPORT_C OMX_ERRORTYPE
       
   634 COmxILInContextCallbackManager::PortSettingsChangeNotification(
       
   635 	OMX_U32 aLocalPortIndex,
       
   636 	TUint aPortSettingsIndex,
       
   637 	const TDesC8& aPortSettings)
       
   638 	{
       
   639     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::PortSettingsChangeNotification : aLocalPortIndex[%d]"), aLocalPortIndex);
       
   640 
       
   641 	LockCallbackManager();
       
   642 	OMX_ERRORTYPE omxError = DoPortSettingsChangeNotification(aLocalPortIndex,
       
   643 															  aPortSettingsIndex,
       
   644 															  aPortSettings);
       
   645 	UnlockCallbackManager();
       
   646 	return omxError;
       
   647 
       
   648 	}
       
   649 
       
   650 
       
   651 void
       
   652 COmxILInContextCallbackManager::FlushQueue(
       
   653 	RCbMgrBufferQueue& aQueue)
       
   654 	{
       
   655     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::FlushQueue : Handle[%X]"), ipHandle);
       
   656 
       
   657 	LockCallbackManager();
       
   658 
       
   659 	TInt i = 0;
       
   660 	while(i < aQueue.Count())
       
   661 		{
       
   662 		TOmxILBuffer buffer(aQueue[i]);
       
   663 		aQueue.Remove(i);
       
   664 		DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::FlushQueue() : FOUND  -> buffer header [%X] PortIndex[%d], queue items [%d]"), buffer.ipBufferHeader, buffer.iLocalPortIndex, aQueue.Count());
       
   665 
       
   666 		UnlockCallbackManager();
       
   667 		ProcessBufferDoneNotification(buffer.ipBufferHeader,
       
   668 									  buffer.iLocalPortIndex,
       
   669 									  buffer.iLocalPortDirection);
       
   670 		LockCallbackManager();
       
   671 		// There is a window where new items could have been added to the
       
   672 		// queue. Restart loop just in case...
       
   673 		i = 0;
       
   674 		}
       
   675 
       
   676 	UnlockCallbackManager();
       
   677 	}
       
   678 
       
   679 TBool
       
   680 COmxILInContextCallbackManager::RemoveBuffersByBufferHeader(
       
   681 	RCbMgrBufferQueue& aQueue,
       
   682 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   683 	const OMX_DIRTYPE aDirection)
       
   684 	{
       
   685     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::RemoveBuffersByBufferHeader : Handle[%X]"), ipHandle);
       
   686 
       
   687 	LockCallbackManager();
       
   688 
       
   689 	TInt i = 0;
       
   690 	while(i < aQueue.Count())
       
   691 		{
       
   692 		TOmxILBuffer buffer(aQueue[i]);
       
   693 		if (apBufferHeader == buffer.ipBufferHeader)
       
   694 			{
       
   695 			__ASSERT_DEBUG(aDirection == OMX_DirInput ||
       
   696 						   aDirection == OMX_DirOutput,
       
   697 						   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   698 
       
   699 			DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::RemoveBuffersByBufferHeader() : Nofiying FSM : Handle[%X] aDirection[%X] apBufferHeader[%X]"), ipHandle, aDirection, apBufferHeader);
       
   700 
       
   701 			// Make sure the buffer contents are cleared...
       
   702 			TOmxILUtil::ClearBufferContents(apBufferHeader);
       
   703 
       
   704 			aQueue.Remove(i);
       
   705 			UnlockCallbackManager();
       
   706 
       
   707 			if (aDirection == OMX_DirInput)
       
   708 				{
       
   709 				ipFsm->EmptyThisBuffer(
       
   710 					const_cast<OMX_BUFFERHEADERTYPE*>(apBufferHeader));
       
   711 				}
       
   712 			else
       
   713 				{
       
   714 				ipFsm->FillThisBuffer(
       
   715 					const_cast<OMX_BUFFERHEADERTYPE*>(apBufferHeader));
       
   716 				}
       
   717 
       
   718 			return ETrue;
       
   719 			}
       
   720 		else
       
   721 			{
       
   722 			++i;
       
   723 			}
       
   724 		}
       
   725 
       
   726 	UnlockCallbackManager();
       
   727 
       
   728 	return EFalse;
       
   729 	}
       
   730 
       
   731 
       
   732 void
       
   733 COmxILInContextCallbackManager::FlushBuffersByPortIndex(
       
   734 	RCbMgrBufferQueue& aQueue,
       
   735 	const OMX_U32 aLocalPortIndex)
       
   736 	{
       
   737     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::FlushBuffersByPortIndex : Handle[%X]"), ipHandle);
       
   738 
       
   739 	LockCallbackManager();
       
   740 
       
   741 	TInt i = 0;
       
   742 	while(i < aQueue.Count())
       
   743 		{
       
   744 		TOmxILBuffer buffer(aQueue[i]);
       
   745 		DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::FlushBuffersByPortIndex() : LOOKING  -> buffer header [%X] PortIndex[%d], queue items [%d]"), buffer.ipBufferHeader, aLocalPortIndex, aQueue.Count());
       
   746 		if (aLocalPortIndex == buffer.iLocalPortIndex)
       
   747 			{
       
   748 			aQueue.Remove(i);
       
   749 			DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::FlushBuffersByPortIndex() : FOUND  -> buffer header [%X] PortIndex[%d], queue items [%d]"), buffer.ipBufferHeader, aLocalPortIndex, aQueue.Count());
       
   750 			UnlockCallbackManager();
       
   751 			ProcessBufferDoneNotification(buffer.ipBufferHeader,
       
   752 										  buffer.iLocalPortIndex,
       
   753 										  buffer.iLocalPortDirection);
       
   754 			LockCallbackManager();
       
   755 			// There is a window where new items could have been added to the
       
   756 			// queue. Restart loop just in case...
       
   757 			i = 0;
       
   758 			}
       
   759 		else
       
   760 			{
       
   761 			++i;
       
   762 			}
       
   763 		}
       
   764 
       
   765 	UnlockCallbackManager();
       
   766 
       
   767 	}
       
   768