omxil_generic/omxilcomplib/src/omxilincontextcallbackmanager.cpp
changeset 0 0e4a32b9112d
child 5 fb6faddbb212
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 "omxilincontextcallbackmanager.h"
       
    24 #include "omxilfsm.h"
       
    25 #include <openmax/il/common/omxilstatedefs.h>
       
    26 #include <openmax/il/common/omxilutil.h>
       
    27 
       
    28 COmxILInContextCallbackManager*
       
    29 COmxILInContextCallbackManager::NewL(
       
    30 	OMX_HANDLETYPE apComponentHandle,
       
    31 	OMX_PTR apAppData,
       
    32 	OMX_CALLBACKTYPE* apCallbacks)
       
    33 	{
       
    34     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::NewL"));
       
    35 	COmxILInContextCallbackManager* self = new (ELeave)COmxILInContextCallbackManager(
       
    36 		apComponentHandle,
       
    37 		apAppData,
       
    38 		apCallbacks);
       
    39 	CleanupStack::PushL(self);
       
    40 	self->ConstructL();
       
    41 	CleanupStack::Pop(self);
       
    42 	return self;
       
    43 	}
       
    44 
       
    45 void
       
    46 COmxILInContextCallbackManager::ConstructL()
       
    47 	{
       
    48     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::ConstructL"));
       
    49 
       
    50 	User::LeaveIfError(iLock.CreateLocal());
       
    51 
       
    52 	}
       
    53 
       
    54 COmxILInContextCallbackManager::COmxILInContextCallbackManager(OMX_HANDLETYPE apComponentHandle,
       
    55 											 OMX_PTR apAppData,
       
    56 											 OMX_CALLBACKTYPE* apCallbacks)
       
    57 	:
       
    58 	CBase(),
       
    59 	XOmxILCallbackManagerIfImpl(
       
    60 		static_cast<OMX_COMPONENTTYPE*>(apComponentHandle),
       
    61 		apAppData,
       
    62 		apCallbacks),
       
    63 	iLock(),
       
    64 	iPendingQueue(),
       
    65 	iFlushPendingQueue(EFalse),
       
    66 	iCurrentState(OMX_StateLoaded),
       
    67 	iPreviousState(OMX_StateLoaded)
       
    68 	{
       
    69     DEBUG_PRINTF(_L8("COmxILInContextCallbackManager::COmxILInContextCallbackManager"));
       
    70 	}
       
    71 
       
    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 void
       
    96 COmxILInContextCallbackManager::SetPortManager(MOmxILPortManagerIf& apPortManager)
       
    97 	{
       
    98 	LockCallbackManager();
       
    99 	DoSetPortManager(apPortManager);
       
   100 	UnlockCallbackManager();
       
   101 	}
       
   102 
       
   103 void
       
   104 COmxILInContextCallbackManager::SetFsm(COmxILFsm& apFsm)
       
   105 	{
       
   106 	LockCallbackManager();
       
   107 	DoSetFsm(apFsm);
       
   108 	UnlockCallbackManager();
       
   109 	}
       
   110 
       
   111 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 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 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 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 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 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 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 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 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 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 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 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 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 #ifdef _OMXIL_COMMON_IL516C_ON
       
   651 OMX_ERRORTYPE
       
   652 COmxILInContextCallbackManager::EjectBuffersRequest(
       
   653 	OMX_U32 aLocalOmxPortIndex)
       
   654 	{
       
   655     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::EjectBuffersRequest : aLocalOmxPortIndex[%d]"), aLocalOmxPortIndex);
       
   656 
       
   657 	OMX_ERRORTYPE omxError = DoEjectBuffersRequest(aLocalOmxPortIndex);
       
   658 	return omxError;
       
   659 
       
   660 	}
       
   661 #endif
       
   662 
       
   663 void
       
   664 COmxILInContextCallbackManager::FlushQueue(
       
   665 	RCbMgrBufferQueue& aQueue)
       
   666 	{
       
   667     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::FlushQueue : Handle[%X]"), ipHandle);
       
   668 
       
   669 	LockCallbackManager();
       
   670 
       
   671 	TInt i = 0;
       
   672 	while(i < aQueue.Count())
       
   673 		{
       
   674 		TOmxILBuffer buffer(aQueue[i]);
       
   675 		aQueue.Remove(i);
       
   676 		DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::FlushQueue() : FOUND  -> buffer header [%X] PortIndex[%d], queue items [%d]"), buffer.ipBufferHeader, buffer.iLocalPortIndex, aQueue.Count());
       
   677 
       
   678 		UnlockCallbackManager();
       
   679 		ProcessBufferDoneNotification(buffer.ipBufferHeader,
       
   680 									  buffer.iLocalPortIndex,
       
   681 									  buffer.iLocalPortDirection);
       
   682 		LockCallbackManager();
       
   683 		// There is a window where new items could have been added to the
       
   684 		// queue. Restart loop just in case...
       
   685 		i = 0;
       
   686 		}
       
   687 
       
   688 	UnlockCallbackManager();
       
   689 	}
       
   690 
       
   691 TBool
       
   692 COmxILInContextCallbackManager::RemoveBuffersByBufferHeader(
       
   693 	RCbMgrBufferQueue& aQueue,
       
   694 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   695 	const OMX_DIRTYPE aDirection)
       
   696 	{
       
   697     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::RemoveBuffersByBufferHeader : Handle[%X]"), ipHandle);
       
   698 
       
   699 	LockCallbackManager();
       
   700 
       
   701 	TInt i = 0;
       
   702 	while(i < aQueue.Count())
       
   703 		{
       
   704 		TOmxILBuffer buffer(aQueue[i]);
       
   705 		if (apBufferHeader == buffer.ipBufferHeader)
       
   706 			{
       
   707 			__ASSERT_DEBUG(aDirection == OMX_DirInput ||
       
   708 						   aDirection == OMX_DirOutput,
       
   709 						   User::Panic(KOmxILCallbackManagerPanicCategory, 1));
       
   710 
       
   711 			DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::RemoveBuffersByBufferHeader() : Nofiying FSM : Handle[%X] aDirection[%X] apBufferHeader[%X]"), ipHandle, aDirection, apBufferHeader);
       
   712 
       
   713 			// Make sure the buffer contents are cleared...
       
   714 			TOmxILUtil::ClearBufferContents(apBufferHeader);
       
   715 
       
   716 			aQueue.Remove(i);
       
   717 			UnlockCallbackManager();
       
   718 
       
   719 			if (aDirection == OMX_DirInput)
       
   720 				{
       
   721 				ipFsm->EmptyThisBuffer(
       
   722 					const_cast<OMX_BUFFERHEADERTYPE*>(apBufferHeader));
       
   723 				}
       
   724 			else
       
   725 				{
       
   726 				ipFsm->FillThisBuffer(
       
   727 					const_cast<OMX_BUFFERHEADERTYPE*>(apBufferHeader));
       
   728 				}
       
   729 
       
   730 			return ETrue;
       
   731 			}
       
   732 		else
       
   733 			{
       
   734 			++i;
       
   735 			}
       
   736 		}
       
   737 
       
   738 	UnlockCallbackManager();
       
   739 
       
   740 	return EFalse;
       
   741 	}
       
   742 
       
   743 
       
   744 void
       
   745 COmxILInContextCallbackManager::FlushBuffersByPortIndex(
       
   746 	RCbMgrBufferQueue& aQueue,
       
   747 	const OMX_U32 aLocalPortIndex)
       
   748 	{
       
   749     DEBUG_PRINTF2(_L8("COmxILInContextCallbackManager::FlushBuffersByPortIndex : Handle[%X]"), ipHandle);
       
   750 
       
   751 	LockCallbackManager();
       
   752 
       
   753 	TInt i = 0;
       
   754 	while(i < aQueue.Count())
       
   755 		{
       
   756 		TOmxILBuffer buffer(aQueue[i]);
       
   757 		DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::FlushBuffersByPortIndex() : LOOKING  -> buffer header [%X] PortIndex[%d], queue items [%d]"), buffer.ipBufferHeader, aLocalPortIndex, aQueue.Count());
       
   758 		if (aLocalPortIndex == buffer.iLocalPortIndex)
       
   759 			{
       
   760 			aQueue.Remove(i);
       
   761 			DEBUG_PRINTF4(_L8("COmxILInContextCallbackManager::FlushBuffersByPortIndex() : FOUND  -> buffer header [%X] PortIndex[%d], queue items [%d]"), buffer.ipBufferHeader, aLocalPortIndex, aQueue.Count());
       
   762 			UnlockCallbackManager();
       
   763 			ProcessBufferDoneNotification(buffer.ipBufferHeader,
       
   764 										  buffer.iLocalPortIndex,
       
   765 										  buffer.iLocalPortDirection);
       
   766 			LockCallbackManager();
       
   767 			// There is a window where new items could have been added to the
       
   768 			// queue. Restart loop just in case...
       
   769 			i = 0;
       
   770 			}
       
   771 		else
       
   772 			{
       
   773 			++i;
       
   774 			}
       
   775 		}
       
   776 
       
   777 	UnlockCallbackManager();
       
   778 
       
   779 	}
       
   780