omxil/omxilcomponentcommon/src/common/omxilcallbackmanagerifimpl.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 "omxilcallbackmanagerifimpl.h"
       
    24 #include "omxilportmanager.h"
       
    25 #include "omxilfsm.h"
       
    26 
       
    27 
       
    28 EXPORT_C
       
    29 XOmxILCallbackManagerIfImpl::XOmxILCallbackManagerIfImpl(OMX_HANDLETYPE apComponentHandle,
       
    30 											 OMX_PTR apAppData,
       
    31 											 OMX_CALLBACKTYPE* apCallbacks)
       
    32 	:
       
    33 	ipHandle(static_cast<OMX_COMPONENTTYPE*>(apComponentHandle)),
       
    34 	ipAppData(apAppData),
       
    35 	ipCallbacks(apCallbacks),
       
    36 	iRegisteredTunnels(),
       
    37 	iBufferMarkPropagationPorts(),
       
    38 	iBufferMarks(),
       
    39 	ipPortManager(0),
       
    40 	ipFsm(0)
       
    41 	{
       
    42     DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::XOmxILCallbackManagerIfImpl"));
       
    43 	}
       
    44 
       
    45 EXPORT_C
       
    46 XOmxILCallbackManagerIfImpl::~XOmxILCallbackManagerIfImpl()
       
    47 	{
       
    48     DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::~XOmxILCallbackManagerIfImpl"));
       
    49 	// These pointers are cleared to make sure that any further calls on this
       
    50 	// object will fail (e.g., from a threaded PF)
       
    51 	ipHandle	= 0;
       
    52 	ipAppData	= 0;
       
    53 	ipCallbacks = 0;
       
    54 
       
    55 	iRegisteredTunnels.Close();
       
    56 	iBufferMarkPropagationPorts.Close();
       
    57 	iBufferMarks.Close();
       
    58 
       
    59 	ipPortManager = 0;
       
    60 
       
    61 	ipFsm = 0;
       
    62 
       
    63 	}
       
    64 
       
    65 EXPORT_C void
       
    66 XOmxILCallbackManagerIfImpl::DoSetPortManager(COmxILPortManager& apPortManager)
       
    67 	{
       
    68 	ipPortManager = &apPortManager;
       
    69 	}
       
    70 
       
    71 EXPORT_C void
       
    72 XOmxILCallbackManagerIfImpl::DoSetFsm(COmxILFsm& apFsm)
       
    73 	{
       
    74 	ipFsm = &apFsm;
       
    75 	}
       
    76 
       
    77 EXPORT_C OMX_ERRORTYPE
       
    78 XOmxILCallbackManagerIfImpl::DoRegisterComponentHandle(OMX_HANDLETYPE aComponentHandle)
       
    79 	{
       
    80     DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::DoRegisterComponentHandle"));
       
    81 
       
    82 	__ASSERT_DEBUG(aComponentHandle,
       
    83 				   User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
    84 
       
    85 	ipHandle = static_cast<OMX_COMPONENTTYPE *>(aComponentHandle);
       
    86 
       
    87 	return OMX_ErrorNone;
       
    88 
       
    89 	}
       
    90 
       
    91 
       
    92 EXPORT_C OMX_ERRORTYPE
       
    93 XOmxILCallbackManagerIfImpl::DoRegisterILClientCallbacks(const OMX_CALLBACKTYPE* apCallbacks,
       
    94 												   const OMX_PTR apAppData)
       
    95 	{
       
    96     DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::DoRegisterILClientCallbacks"));
       
    97 
       
    98 	ipAppData   = const_cast<OMX_PTR>(apAppData);
       
    99 	ipCallbacks = const_cast<OMX_CALLBACKTYPE*>(apCallbacks);
       
   100 
       
   101 	return OMX_ErrorNone;
       
   102 
       
   103 	}
       
   104 
       
   105 EXPORT_C OMX_ERRORTYPE
       
   106 XOmxILCallbackManagerIfImpl::DoRegisterTunnelCallback(
       
   107 	OMX_U32 aLocalPortIndex,
       
   108 	OMX_DIRTYPE aLocalPortDirection,
       
   109 	OMX_HANDLETYPE aTunnelledComponentHandle,
       
   110 	OMX_U32 aTunnelledPortIndex)
       
   111 	{
       
   112 	DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::DoRegisterTunnelCallback"));
       
   113 
       
   114 	OMX_ERRORTYPE omxError = OMX_ErrorNone;
       
   115 
       
   116 	if (aTunnelledComponentHandle)
       
   117 		{
       
   118 		// Register tunnelled port
       
   119 		TInt err = iRegisteredTunnels.Append(
       
   120 			TTunnelRegistrationInfo(aLocalPortIndex,
       
   121 									aLocalPortDirection,
       
   122 									aTunnelledComponentHandle,
       
   123 									aTunnelledPortIndex));
       
   124 		if (KErrNone != err)
       
   125 			{
       
   126 			switch (err)
       
   127 				{
       
   128 			case KErrNoMemory:
       
   129 				{
       
   130 				omxError = OMX_ErrorInsufficientResources;
       
   131 				}
       
   132 				break;
       
   133 			default:
       
   134 				{
       
   135 				omxError = OMX_ErrorUndefined;
       
   136 				}
       
   137 				};
       
   138 			}
       
   139 
       
   140 		}
       
   141 	else
       
   142 		{
       
   143 		// Deregister tunnelled port
       
   144 		const TUint tunnelCount = iRegisteredTunnels.Count();
       
   145 		for (TUint i=0; i<tunnelCount; ++i)
       
   146 			{
       
   147 			if (iRegisteredTunnels[i].iLocalPortIndex ==
       
   148 				aLocalPortIndex)
       
   149 				{
       
   150 				iRegisteredTunnels.Remove(i);
       
   151 				break;
       
   152 				}
       
   153 			}
       
   154 		}
       
   155 
       
   156 	return omxError;
       
   157 
       
   158 	}
       
   159 
       
   160 EXPORT_C OMX_ERRORTYPE
       
   161 XOmxILCallbackManagerIfImpl::DoRegisterBufferMarkPropagationPort(
       
   162 	OMX_U32 aPortIndex,
       
   163 	OMX_U32 aPropagationPortIndex)
       
   164 	{
       
   165 	DEBUG_PRINTF3(_L8("XOmxILCallbackManagerIfImpl::DoRegisterBufferMarkPropagationPort : aPortIndex[%d] aPropagationPortIndex[%d] "),aPortIndex, aPropagationPortIndex);
       
   166 
       
   167 	TInt err = iBufferMarkPropagationPorts.Append(
       
   168 		TBufferMarkPropagationInfo(aPortIndex,
       
   169 								   aPropagationPortIndex));
       
   170 
       
   171 	OMX_ERRORTYPE omxError = OMX_ErrorNone;
       
   172 	if (KErrNone != err)
       
   173 		{
       
   174 		switch (err)
       
   175 			{
       
   176 		case KErrNoMemory:
       
   177 			{
       
   178 			omxError = OMX_ErrorInsufficientResources;
       
   179 			}
       
   180 			break;
       
   181 		default:
       
   182 			{
       
   183 			omxError = OMX_ErrorUndefined;
       
   184 			}
       
   185 			};
       
   186 		}
       
   187 
       
   188 	return omxError;
       
   189 
       
   190 	}
       
   191 
       
   192 
       
   193 
       
   194 EXPORT_C OMX_ERRORTYPE
       
   195 XOmxILCallbackManagerIfImpl::DoTransitionCompleteNotification(OMX_STATETYPE aOmxState)
       
   196 	{
       
   197     DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::DoTransitionCompleteNotification"));
       
   198 
       
   199 	return DoEventNotification(OMX_EventCmdComplete,
       
   200 							 OMX_CommandStateSet,
       
   201 							 aOmxState,
       
   202 							 0);
       
   203 
       
   204 	}
       
   205 
       
   206 
       
   207 EXPORT_C OMX_ERRORTYPE
       
   208 XOmxILCallbackManagerIfImpl::DoCommandCompleteNotification(OMX_COMMANDTYPE aOmxCommand,
       
   209 												   OMX_U32 aOmxPortIndex)
       
   210 	{
       
   211     DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::DoCommandCompleteNotification"));
       
   212 
       
   213 	return DoEventNotification(OMX_EventCmdComplete,
       
   214 							 aOmxCommand,
       
   215 							 aOmxPortIndex,
       
   216 							 0);
       
   217 
       
   218 	}
       
   219 
       
   220 
       
   221 EXPORT_C OMX_ERRORTYPE
       
   222 XOmxILCallbackManagerIfImpl::DoErrorEventNotification(OMX_ERRORTYPE aOmxError)
       
   223 	{
       
   224     DEBUG_PRINTF2(_L8("XOmxILCallbackManagerIfImpl::DoErrorEventNotification : aOmxError[%X] "), aOmxError);
       
   225 
       
   226 	return DoEventNotification(OMX_EventError,
       
   227 							 aOmxError,
       
   228 							 0,
       
   229 							 0);
       
   230 
       
   231 	}
       
   232 
       
   233 EXPORT_C OMX_ERRORTYPE
       
   234 XOmxILCallbackManagerIfImpl::DoEventNotification(OMX_EVENTTYPE aEvent,
       
   235 										   TUint32 aData1,
       
   236 										   TUint32 aData2,
       
   237 										   OMX_STRING aExtraInfo)
       
   238 	{
       
   239     DEBUG_PRINTF4(_L8("XOmxILCallbackManagerIfImpl::DoEventNotification : aEvent[%u] aData1[%u] aData2[%u]"), aEvent, aData1, aData2);
       
   240 
       
   241 	__ASSERT_DEBUG(ipHandle && ipCallbacks, User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   242 
       
   243 	ipCallbacks->EventHandler(ipHandle,
       
   244 							  ipAppData,
       
   245 							  aEvent,
       
   246 							  aData1,
       
   247 							  aData2,
       
   248 							  aExtraInfo);
       
   249 	return OMX_ErrorNone;
       
   250 
       
   251 	}
       
   252 
       
   253 
       
   254 EXPORT_C OMX_ERRORTYPE
       
   255 XOmxILCallbackManagerIfImpl::DoBufferDoneNotification(OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   256 											 OMX_U32 aLocalPortIndex,
       
   257 											 OMX_DIRTYPE aLocalPortDirection)
       
   258 	{
       
   259     DEBUG_PRINTF5(_L8("XOmxILCallbackManagerIfImpl::DoBufferDoneNotification : HANDLE [%X] BUFFER [%X] PORT[%d] DIR[%d]"), ipHandle, apBufferHeader, aLocalPortIndex, aLocalPortDirection);
       
   260 
       
   261 	__ASSERT_ALWAYS(apBufferHeader &&
       
   262 					(OMX_DirInput == aLocalPortDirection ||
       
   263 					 OMX_DirOutput == aLocalPortDirection),
       
   264 					User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   265 
       
   266 	__ASSERT_ALWAYS(apBufferHeader->nOffset + apBufferHeader->nFilledLen
       
   267 					<= apBufferHeader->nAllocLen,
       
   268 					User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   269 
       
   270 	__ASSERT_DEBUG(ipHandle && ipCallbacks, User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   271 
       
   272 	// Look for buffer marks to be signalled or propagated
       
   273 	SignalOrPropagateBufferMarks(apBufferHeader,
       
   274 								 aLocalPortDirection);
       
   275 
       
   276 	// find out whether the port is tunnelled or not
       
   277 	TBool tunnelled = EFalse;
       
   278 	TUint tunnelInfoArrayIndex = 0;
       
   279 	const TUint tunnelCount = iRegisteredTunnels.Count();
       
   280 	for (TUint i=0; i<tunnelCount; ++i)
       
   281 		{
       
   282 		if (iRegisteredTunnels[i].iLocalPortIndex ==
       
   283 			aLocalPortIndex)
       
   284 			{
       
   285 			tunnelled = ETrue;
       
   286 			tunnelInfoArrayIndex = i;
       
   287 			break;
       
   288 			}
       
   289 		}
       
   290 
       
   291 	if (tunnelled)
       
   292 		{
       
   293 		OMX_COMPONENTTYPE* ipTunnelledComponent =
       
   294 			static_cast<OMX_COMPONENTTYPE*>(
       
   295 				iRegisteredTunnels[tunnelInfoArrayIndex].
       
   296 				iTunnelledComponentHandle);
       
   297 
       
   298 		__ASSERT_DEBUG(ipTunnelledComponent,
       
   299 					   User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   300 
       
   301 		// From OMX_Core.h "Callbacks should not return an error to the
       
   302 		// component, so if an error occurs, the application shall handle it
       
   303 		// internally". Callback return error ignored here.
       
   304 		if (OMX_DirInput == aLocalPortDirection)
       
   305 			{
       
   306 			OMX_FillThisBuffer(ipTunnelledComponent, apBufferHeader);
       
   307 			}
       
   308 		else
       
   309 			{
       
   310 			OMX_EmptyThisBuffer(ipTunnelledComponent, apBufferHeader);
       
   311 			}
       
   312 
       
   313 		}
       
   314 	else
       
   315 		{
       
   316 		OMX_ERRORTYPE (*fp2CBackHandler)
       
   317 			(OMX_HANDLETYPE, OMX_PTR, OMX_BUFFERHEADERTYPE*) =
       
   318 			(aLocalPortDirection == OMX_DirInput ?
       
   319 			 ipCallbacks->EmptyBufferDone :
       
   320 			 ipCallbacks->FillBufferDone);
       
   321 
       
   322 		// From OMX_Core.h "Callbacks should not return an error to the
       
   323 		// component, so if an error occurs, the application shall handle it
       
   324 		// internally". Callback return error ignored here.
       
   325 		fp2CBackHandler(ipHandle,
       
   326 						ipAppData,
       
   327 						apBufferHeader);
       
   328 		}
       
   329 
       
   330 	return OMX_ErrorNone;
       
   331 
       
   332 	}
       
   333 
       
   334 EXPORT_C OMX_ERRORTYPE
       
   335 XOmxILCallbackManagerIfImpl::DoPortSettingsChangeNotification(
       
   336 	OMX_U32 aLocalPortIndex,
       
   337 	TUint aPortSettingsIndex,
       
   338 	const TDesC8& aPortSettings)
       
   339 	{
       
   340     DEBUG_PRINTF2(_L8("XOmxILCallbackManagerIfImpl::DoPortSettingsChangeNotification : aLocalPortIndex[%d]"), aLocalPortIndex);
       
   341 
       
   342 	__ASSERT_DEBUG(ipHandle &&
       
   343 				   ipCallbacks &&
       
   344 				   ipPortManager,
       
   345 				   User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   346 
       
   347 	HBufC8* pPortSettings = HBufC8::New(aPortSettings.Length());
       
   348 	if (!pPortSettings)
       
   349 		{
       
   350 		return OMX_ErrorInsufficientResources;
       
   351 		}
       
   352 	*pPortSettings = aPortSettings;
       
   353 
       
   354 	// This is an event that the port may want to convey to the IL Client...
       
   355 	OMX_EVENTTYPE eventForILClient = OMX_EventMax;
       
   356 	OMX_ERRORTYPE omxRetError =
       
   357 		ipPortManager->PortSettingsChangeIndication(aLocalPortIndex,
       
   358 													aPortSettingsIndex,
       
   359 													*pPortSettings,
       
   360 													eventForILClient);
       
   361 
       
   362 	delete pPortSettings;
       
   363 	pPortSettings = NULL;
       
   364 
       
   365 	// Inform the IL Client that some value in one of the ports' configuration
       
   366 	// structures has changed...
       
   367 	if (OMX_EventMax != eventForILClient)
       
   368 		{
       
   369 		// Only allow these two port events...
       
   370 		__ASSERT_ALWAYS(eventForILClient == OMX_EventPortSettingsChanged ||
       
   371 						eventForILClient == OMX_EventPortFormatDetected,
       
   372 						User::Panic(KOmxILCallbackManagerIfImplPanicCategory, 1));
       
   373 
       
   374 		// From OMX_Core.h "Callbacks should not return an error to the component,
       
   375 		// so if an error occurs, the application shall handle it
       
   376 		// internally". Callback return error ignored here.
       
   377 		ipCallbacks->EventHandler(ipHandle,
       
   378 								  ipAppData,
       
   379 								  eventForILClient,
       
   380 								  aLocalPortIndex,
       
   381 								  0,
       
   382 								  0);
       
   383 		}
       
   384 
       
   385 	return OMX_ErrorNone;
       
   386 
       
   387 	}
       
   388 
       
   389 EXPORT_C void
       
   390 XOmxILCallbackManagerIfImpl::SignalOrPropagateBufferMarks(
       
   391 	OMX_BUFFERHEADERTYPE* apBufferHeader,
       
   392 	OMX_U32 aLocalPortIndex)
       
   393 	{
       
   394     DEBUG_PRINTF(_L8("XOmxILCallbackManagerIfImpl::SignalOrPropagateBufferMarks()"));
       
   395 
       
   396 	// Look for buffer marks to be signalled or propagated
       
   397 	if (apBufferHeader->hMarkTargetComponent)
       
   398 		{
       
   399 		// See if this component is the buffer mark target component...
       
   400 		if (apBufferHeader->hMarkTargetComponent == ipHandle)
       
   401 			{
       
   402 			// Inform the IL Client that a marked buffer has been processed...
       
   403 			ipCallbacks->EventHandler(ipHandle,
       
   404 									  ipAppData,
       
   405 									  OMX_EventMark,
       
   406 									  0,
       
   407 									  0,
       
   408 									  apBufferHeader->pMarkData);
       
   409 
       
   410 			// At this point, the mark has been delivered to the IL
       
   411 			// Client...Remove the mark from the processed header...
       
   412 			apBufferHeader->hMarkTargetComponent = 0;
       
   413 			apBufferHeader->pMarkData = 0;
       
   414 
       
   415 			}
       
   416 		else
       
   417 			{
       
   418 			// Propagate the mark...
       
   419 
       
   420 			// First find the buffer mark propagation port...
       
   421 			const TInt index = iBufferMarkPropagationPorts.Find(
       
   422 				TBufferMarkPropagationInfo(aLocalPortIndex),
       
   423 				TIdentityRelation<TBufferMarkPropagationInfo>(
       
   424 					&TBufferMarkPropagationInfo::Compare));
       
   425 
       
   426 			// Note that sink components don't propagate marks...
       
   427 			if (index != KErrNotFound)
       
   428 				{
       
   429 				const TBufferMarkPropagationInfo& propInfo =
       
   430 					iBufferMarkPropagationPorts[index];
       
   431 
       
   432 				// Let's check for the special case: The case for a source
       
   433 				// component where the output port is both the port that marks
       
   434 				// the headers and the port that propagates them ... Therefore
       
   435 				// no need to store the mark for later propagation...
       
   436 				if (propInfo.iPropagationPortIndex != aLocalPortIndex)
       
   437 					{
       
   438 					// Now, store temporarily the mark so the next time we send
       
   439 					// a buffer done callback in that propagation port, we mark
       
   440 					// that header accordingly...
       
   441 					// Unsuccessful insertion is ignored.
       
   442 					iBufferMarks.Append(
       
   443 						TOutputPortBufferMarkInfo(
       
   444 							propInfo.iPropagationPortIndex,
       
   445 							apBufferHeader->hMarkTargetComponent,
       
   446 							apBufferHeader->pMarkData));
       
   447 
       
   448 					// At this point the mark has been set for propagation to
       
   449 					// an output port. Remove the mark from the processed
       
   450 					// header...
       
   451 					apBufferHeader->hMarkTargetComponent = 0;
       
   452 					apBufferHeader->pMarkData = 0;
       
   453 					}
       
   454 				}
       
   455 			}
       
   456 		}
       
   457 	else
       
   458 		{
       
   459 		if(iBufferMarks.Count() != 0)
       
   460 			{
       
   461 			// Let's see if we have a mark waiting to go out...This will find the
       
   462 			// first mark in the local list of marks ...
       
   463 			const TInt index = iBufferMarks.Find(
       
   464 				TOutputPortBufferMarkInfo(aLocalPortIndex),
       
   465 				TIdentityRelation<TOutputPortBufferMarkInfo>(
       
   466 					&TOutputPortBufferMarkInfo::Compare));
       
   467 			if (index != KErrNotFound)
       
   468 				{
       
   469 				const TOutputPortBufferMarkInfo& markInfo =
       
   470 					iBufferMarks[index];
       
   471 
       
   472 				// Mark the header...
       
   473 				apBufferHeader->hMarkTargetComponent = markInfo.ipMarkTargetComponent;
       
   474 				apBufferHeader->pMarkData			 = markInfo.ipMarkData;
       
   475 
       
   476 				// Remove the mark info from the local store
       
   477 				iBufferMarks.Remove(index);
       
   478 				}
       
   479 			}
       
   480 
       
   481 		}
       
   482 
       
   483 
       
   484 	}
       
   485 
       
   486 EXPORT_C void
       
   487 XOmxILCallbackManagerIfImpl::HandleInsufficientResources()
       
   488 	{
       
   489     DEBUG_PRINTF3(_L8("XOmxILCallbackManagerIfImpl::HandleInsufficientResources : ipCallbacks[%X] ipHandle[%X]"), ipCallbacks, ipHandle);
       
   490 
       
   491 	if (ipCallbacks && ipHandle)
       
   492 		{
       
   493 		// This is a best-effort action, let's try to inform the IL Client of
       
   494 		// the lack of resources...
       
   495 		ipCallbacks->EventHandler(ipHandle,
       
   496 								  ipAppData,
       
   497 								  OMX_EventError,
       
   498 					  			  (OMX_U32)OMX_ErrorInsufficientResources,
       
   499 								  0,
       
   500 								  0);
       
   501 		}
       
   502 	}