mmdevicefw/mdf/src/openmax/omxcomponentbody.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2005-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 #include <e32base.h>
       
    17 #include <e32msgqueue.h>
       
    18 #include <mmf/server/mmfdatabuffer.h>
       
    19 #include "omxcomponentbody.h"
       
    20 #include "omxcomponentimpl.h"
       
    21 
       
    22 const TInt KMaxMsgQueueEntries = 10;
       
    23 const TInt KMaxComponentNameLength = 256;
       
    24 
       
    25 const TInt KSymbianErrors[] =
       
    26 	{
       
    27 	KErrNoMemory, /*OMX_ErrorInsufficientResources*/
       
    28 	KErrUnknown,
       
    29 	KErrBadName,
       
    30 	KErrNotFound,
       
    31 	KErrGeneral, /*OMX_ErrorInvalidComponent*/
       
    32 	KErrArgument, /*OMX_ErrorBadParameter*/
       
    33 	KErrNotSupported, /*OMX_ErrorNotImplemented*/
       
    34 	KErrUnderflow, /*OMX_ErrorUnderflow*/
       
    35 	KErrOverflow, /*OMX_ErrorOverflow*/
       
    36 	KErrHardwareNotAvailable, /* OMX_ErrorHardware*/
       
    37 	KErrGeneral, /*OMX_ErrorInvalidState*/
       
    38   	KErrCorrupt, /*OMX_ErrorStreamCorrupt*/
       
    39   	KErrArgument, /*OMX_ErrorPortsNotCompatible*/
       
    40   	KErrHardwareNotAvailable, /*OMX_ErrorResourcesLost*/
       
    41   	KErrCompletion, /*OMX_ErrorNoMore*/ 
       
    42   	KErrGeneral, /*OMX_ErrorVersionMismatch*/
       
    43   	KErrNotReady, /*OMX_ErrorNotReady*/
       
    44   	KErrTimedOut, /*OMX_ErrorTimeout*/
       
    45   	KErrNone /*OMX_ErrorSameState*/
       
    46 	};
       
    47 
       
    48 /**
       
    49  Converts an OpenMAX error code to a Symbian error code.
       
    50  @param		aErrorType The OpenMAX error code.
       
    51  @return	The Symbian error code.
       
    52  */
       
    53 TInt ConvertOmxErrorType(OMX_ERRORTYPE aErrorType)
       
    54 	{
       
    55 	if (aErrorType == OMX_ErrorNone)
       
    56 		{
       
    57 		return KErrNone;
       
    58 		}
       
    59 	else if (aErrorType >= OMX_ErrorInsufficientResources &&
       
    60 			  aErrorType <= OMX_ErrorSameState)
       
    61 		{
       
    62 		return KSymbianErrors[aErrorType - OMX_ErrorInsufficientResources];
       
    63 		}
       
    64 	else
       
    65 		{
       
    66 		return KErrGeneral;
       
    67 		}
       
    68 	}
       
    69 	
       
    70 /**
       
    71  Converts a Symbian error code to an OpenMAX error code.
       
    72  @param		aError The Symbian error code.
       
    73  @return	The OpenMAX error code.
       
    74  */
       
    75 OMX_ERRORTYPE ConvertSymbianErrorType(TInt aError)
       
    76 	{
       
    77 	OMX_ERRORTYPE err = OMX_ErrorNone;
       
    78 	switch (aError)
       
    79 		{
       
    80 	case KErrNone:
       
    81 		err = OMX_ErrorNone;
       
    82 		break;
       
    83 	case KErrNoMemory:
       
    84 		err = OMX_ErrorInsufficientResources;
       
    85 		break;
       
    86 	case KErrGeneral:
       
    87 		break;
       
    88 	default:
       
    89 		err = OMX_ErrorUndefined;
       
    90 		}
       
    91 	return err;
       
    92 	}
       
    93 
       
    94 
       
    95 COmxBufferManager::COmxBufferManager(OMX_COMPONENTTYPE* aHandle)
       
    96 	: iHandle(aHandle)
       
    97 	{
       
    98 	}
       
    99 	
       
   100 COmxBufferManager::COmxBuffer::COmxBuffer()
       
   101 	{
       
   102 	}
       
   103 	
       
   104 	
       
   105 COmxBufferManager::COmxBuffer* COmxBufferManager::COmxBuffer::NewL(OMX_BUFFERHEADERTYPE* aBufferHeader, CMMFBuffer* aBuffer)
       
   106 	{
       
   107 	COmxBuffer* self = new (ELeave) COmxBuffer;
       
   108 	CleanupStack::PushL(self);
       
   109 	self->ConstructL(aBufferHeader, aBuffer);
       
   110 	CleanupStack::Pop(self);
       
   111 	return self;
       
   112 	}
       
   113 	
       
   114 COmxBufferManager::COmxBuffer::~COmxBuffer()
       
   115 	{
       
   116 	if (iOwnsMmfBuffer)
       
   117 		{
       
   118 		delete iMmfBuffer;
       
   119 		}
       
   120 	}
       
   121 	
       
   122 	
       
   123 CMMFBuffer* COmxBufferManager::COmxBuffer::MmfBuffer() const
       
   124 	{
       
   125 	return iMmfBuffer;
       
   126 	}
       
   127 	
       
   128 OMX_BUFFERHEADERTYPE* COmxBufferManager::COmxBuffer::BufferHeader() const
       
   129 	{
       
   130 	return iBufferHeader;
       
   131 	}
       
   132 
       
   133 
       
   134 MOmxInputPortCallbacks* COmxBufferManager::COmxBuffer::InputPortCallbacks() const
       
   135 	{
       
   136 	return iInputPortCallbacks;
       
   137 	}
       
   138 	
       
   139 MOmxOutputPortCallbacks* COmxBufferManager::COmxBuffer::OutputPortCallbacks() const
       
   140 	{
       
   141 	return iOutputPortCallbacks;
       
   142 	}
       
   143 	
       
   144 void COmxBufferManager::COmxBuffer::SetInputPortCallbacks(MOmxInputPortCallbacks* aCallbacks)
       
   145 	{
       
   146 	iInputPortCallbacks = aCallbacks;
       
   147 	}
       
   148 	
       
   149 void COmxBufferManager::COmxBuffer::SetOutputPortCallbacks(MOmxOutputPortCallbacks* aCallbacks)
       
   150 	{
       
   151 	iOutputPortCallbacks = aCallbacks;
       
   152 	}
       
   153 	
       
   154 // look up the corresponding buffer
       
   155 COmxBufferManager::COmxBuffer* COmxBufferManager::FindBuffer(const CMMFBuffer* aBuffer) const
       
   156 	{
       
   157 	COmxBuffer* buffer = NULL;
       
   158 	for (TInt i=0;i<iBuffers.Count() && !buffer;i++)
       
   159 		{
       
   160 		if (iBuffers[i]->MmfBuffer() == aBuffer)
       
   161 			{
       
   162 			buffer = iBuffers[i];
       
   163 			}
       
   164 		}
       
   165 	return buffer;
       
   166 	}
       
   167 	
       
   168 COmxBufferManager::COmxBuffer* COmxBufferManager::FindBuffer(OMX_BUFFERHEADERTYPE* aBuffer) const
       
   169 	{
       
   170 	return reinterpret_cast<COmxBuffer*>(aBuffer->pAppPrivate);
       
   171 	}
       
   172 
       
   173 	
       
   174 	
       
   175  TInt COmxBufferManager::UseBuffer(CMMFBuffer& aBuffer, TUint aPortIndex)
       
   176 	{
       
   177 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer.Type()))
       
   178 		{
       
   179 		OMX_BUFFERHEADERTYPE* buffer;
       
   180 		CMMFDataBuffer& dataBuffer = static_cast<CMMFDataBuffer&>(aBuffer);
       
   181 				
       
   182         TDes8& aBufferDes = dataBuffer.Data();
       
   183         OMX_ERRORTYPE error = iHandle->UseBuffer(static_cast<OMX_HANDLETYPE>(iHandle), &buffer, aPortIndex, (void*)&aBuffer, aBufferDes.MaxLength(), const_cast<TUint8*>(aBufferDes.Ptr()));
       
   184     	if (error != OMX_ErrorNone)
       
   185     		{
       
   186     		return ConvertOmxErrorType(error);
       
   187     		}
       
   188 		TRAPD(err, StoreBufferL(buffer, &aBuffer));
       
   189 		return err;
       
   190 		}
       
   191 	else
       
   192 		{
       
   193 		return KErrNotSupported;
       
   194 		}
       
   195 	}
       
   196 
       
   197 
       
   198  CMMFBuffer* COmxBufferManager::AllocateBufferL(TUint aPortIndex, TUint aSizeBytes)
       
   199 	{
       
   200 	OMX_BUFFERHEADERTYPE* buffer;
       
   201 	OMX_ERRORTYPE error = iHandle->AllocateBuffer(static_cast<OMX_HANDLETYPE>(iHandle), &buffer, aPortIndex, NULL, aSizeBytes);
       
   202 	User::LeaveIfError(ConvertOmxErrorType(error));
       
   203 
       
   204 	StoreBufferL(buffer,NULL); // transfers ownership
       
   205 
       
   206 	// return the newly created buffer
       
   207 	return FindBuffer(buffer)->MmfBuffer();
       
   208 	}
       
   209 	
       
   210 
       
   211  TInt COmxBufferManager::FreeBuffer(CMMFBuffer* aBuffer)
       
   212 	{
       
   213 	COmxBuffer* buffer;
       
   214 	for (TInt i=0;i<iBuffers.Count();i++)
       
   215 		{
       
   216 		buffer = iBuffers[i];
       
   217 		if (buffer->MmfBuffer() == aBuffer)
       
   218 			{
       
   219 			iBuffers.Remove(i);
       
   220 			OMX_ERRORTYPE err = iHandle->FreeBuffer(static_cast<OMX_HANDLETYPE>(iHandle), 0, buffer->BufferHeader());
       
   221 			delete buffer;
       
   222 			return err;
       
   223 			}
       
   224 		}
       
   225 	return KErrNotFound;
       
   226 	}
       
   227 	
       
   228 void COmxBufferManager::COmxBuffer::ConstructL(OMX_BUFFERHEADERTYPE* aBufferHeader, CMMFBuffer* aBuffer)
       
   229 	{
       
   230 	
       
   231 	// Now if CMMFBuffer is NULL, this is been called from allocate buffer, and we need to 
       
   232 	// Allocate a ptr buffer to correspond to the buffer created by OMX
       
   233 	ASSERT(aBufferHeader);
       
   234 	iBufferHeader = aBufferHeader;	
       
   235 	if (aBuffer == NULL)
       
   236 		{
       
   237 		TPtr8 ptr(iBufferHeader->pBuffer, iBufferHeader->nFilledLen, iBufferHeader->nAllocLen);
       
   238 		CMMFBuffer* mmfBuffer = CMMFPtrBuffer::NewL(ptr);
       
   239 		iMmfBuffer = mmfBuffer;
       
   240 		iOwnsMmfBuffer = ETrue;
       
   241 		}
       
   242 	else
       
   243 		{
       
   244 		iMmfBuffer = aBuffer;
       
   245 		}
       
   246 		
       
   247 	// store pointer to element in array
       
   248 	iBufferHeader->pAppPrivate = this;
       
   249 	}
       
   250 
       
   251 
       
   252 
       
   253 // Store OMX buffer pointer
       
   254 void COmxBufferManager::StoreBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, CMMFBuffer* aBuffer)
       
   255 	{
       
   256 	COmxBuffer* buf = COmxBuffer::NewL(aBufferHeader, aBuffer);
       
   257 	CleanupStack::PushL(buf);
       
   258 	iBuffers.AppendL(buf);
       
   259 	CleanupStack::Pop(buf);
       
   260 	}
       
   261 	
       
   262 	
       
   263  TInt COmxBufferManager::EmptyThisBuffer(const CMMFBuffer* aBuffer, MOmxInputPortCallbacks* aObserver)
       
   264 	{
       
   265 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
       
   266 		{
       
   267 		COmxBuffer* omxBuffer = FindBuffer(aBuffer);
       
   268 		if (!omxBuffer)
       
   269 			{
       
   270 			return KErrNotFound;
       
   271 			}
       
   272 
       
   273 		omxBuffer->SetInputPortCallbacks(aObserver);
       
   274 		OMX_BUFFERHEADERTYPE* bufferHeader = omxBuffer->BufferHeader();
       
   275 		const CMMFDataBuffer* buf = static_cast<const CMMFDataBuffer*>(aBuffer);
       
   276 		const TDesC8& des = buf->Data();
       
   277 		bufferHeader->nFilledLen = des.Length();
       
   278 		bufferHeader->nFlags = 0;
       
   279 		if (aBuffer->LastBuffer())
       
   280 			{	
       
   281 			bufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
       
   282 			}
       
   283 		else
       
   284 			{
       
   285 			bufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
       
   286 			}
       
   287 		return ConvertOmxErrorType(iHandle->EmptyThisBuffer(static_cast<OMX_HANDLETYPE>(iHandle), bufferHeader));
       
   288 		}
       
   289 	else
       
   290 		{
       
   291 		return KErrNotSupported;
       
   292 		}
       
   293 	}
       
   294 
       
   295 
       
   296  TInt COmxBufferManager::FillThisBuffer(CMMFBuffer* aBuffer, MOmxOutputPortCallbacks* aObserver)
       
   297 	{
       
   298 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
       
   299 		{
       
   300 		COmxBuffer* omxBuffer = FindBuffer(aBuffer);
       
   301 		if (!omxBuffer)
       
   302 			{
       
   303 			return KErrNotFound;
       
   304 			}
       
   305 		omxBuffer->SetOutputPortCallbacks(aObserver);
       
   306 		OMX_BUFFERHEADERTYPE* bufferHeader = omxBuffer->BufferHeader();
       
   307 		
       
   308 		bufferHeader->nFilledLen = 0;
       
   309 		// clear last buffer flag
       
   310 		bufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
       
   311 		return ConvertOmxErrorType(iHandle->FillThisBuffer(static_cast<OMX_HANDLETYPE>(iHandle), bufferHeader));
       
   312 		}
       
   313 	else
       
   314 		{
       
   315 		return KErrNotSupported;
       
   316 		}
       
   317 	}
       
   318 
       
   319 	
       
   320 	
       
   321 COmxBufferManager::~COmxBufferManager()
       
   322 	{
       
   323 	for (TInt i=0;i<iBuffers.Count();i++)
       
   324 		{
       
   325 		COmxBuffer* omxBuffer = iBuffers[i];
       
   326 		iHandle->FreeBuffer(static_cast<OMX_HANDLETYPE>(iHandle), 0, omxBuffer->BufferHeader());
       
   327 		delete omxBuffer;
       
   328 		}
       
   329 	iBuffers.Close();
       
   330 	}
       
   331 	
       
   332 //  Implementation of the Class COmxComponent
       
   333 
       
   334 
       
   335 
       
   336 COmxCallbacks* COmxCallbacks::NewL(MOmxPuCallbacks& aPuCallbacks)
       
   337 	{
       
   338 	COmxCallbacks* self = new (ELeave) COmxCallbacks(aPuCallbacks);
       
   339 	CleanupStack::PushL(self);
       
   340 	self->ConstructL();
       
   341 	CleanupStack::Pop(self);
       
   342 	return self;
       
   343 	}
       
   344 	
       
   345 	
       
   346 void COmxCallbacks::ConstructL()
       
   347 	{
       
   348 	OMX_CALLBACKTYPE h =
       
   349 			{
       
   350 			&::EventHandler,
       
   351 			&::EmptyBufferDone,
       
   352 			&::FillBufferDone
       
   353 			};
       
   354 			
       
   355 	iHandle = h;
       
   356 	CActiveScheduler::Add(this);
       
   357 
       
   358 	User::LeaveIfError(iMsgQueue.CreateLocal(KMaxMsgQueueEntries));
       
   359 	iMsgQueue.NotifyDataAvailable(iStatus);
       
   360 	SetActive();
       
   361 	}
       
   362 
       
   363 COmxCallbacks::COmxCallbacks(MOmxPuCallbacks& aPuCallbacks)
       
   364 	: CActive(EPriorityNormal),
       
   365 	iPuCallbacks(&aPuCallbacks)
       
   366 	{
       
   367 	}
       
   368 		
       
   369 	
       
   370 COmxCallbacks::operator OMX_CALLBACKTYPE*()
       
   371 	{
       
   372 	return &iHandle;
       
   373 	}
       
   374 	
       
   375 	
       
   376 void COmxCallbacks::RunL()
       
   377 	{
       
   378 	TOmxMessage msg;
       
   379 	while (iMsgQueue.Receive(msg)==KErrNone)
       
   380 		{
       
   381 		switch (msg.iType)
       
   382 			{
       
   383 			case EEmptyBufferCallback:
       
   384 				{
       
   385 				MOmxInputPortCallbacks* callback = msg.iBuffer->InputPortCallbacks();
       
   386 				const CMMFBuffer* buffer = msg.iBuffer->MmfBuffer();
       
   387 				callback->EmptyBufferDone(msg.iComponent, buffer);
       
   388 				break;
       
   389 				}				
       
   390 
       
   391 			case EFillBufferCallback:
       
   392 				{
       
   393 				CMMFBuffer* mmfBuffer = msg.iBuffer->MmfBuffer();
       
   394 				OMX_BUFFERHEADERTYPE* bufferHeader = msg.iBuffer->BufferHeader();
       
   395 
       
   396 				if (CMMFBuffer::IsSupportedDataBuffer(mmfBuffer->Type()))
       
   397 					{
       
   398 					CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(mmfBuffer);
       
   399 					TDes8& aBufferDes = dataBuffer->Data();
       
   400 					aBufferDes.SetLength(bufferHeader->nFilledLen);
       
   401 					mmfBuffer->SetLastBuffer(bufferHeader->nFlags & OMX_BUFFERFLAG_EOS);
       
   402 					}				
       
   403 				else
       
   404 					{
       
   405 					ASSERT(EFalse);
       
   406 					}
       
   407 				MOmxOutputPortCallbacks* callback = msg.iBuffer->OutputPortCallbacks();
       
   408 				callback->FillBufferDone(msg.iComponent, mmfBuffer);
       
   409 				break;
       
   410 				}				
       
   411 			case EEventCallback:
       
   412 				{
       
   413 				iPuCallbacks->MopcEventHandler(msg.iComponent, 
       
   414 											msg.iEventParams.iEvent, 
       
   415 											msg.iEventParams.iData1, 
       
   416 											msg.iEventParams.iData2, 
       
   417 											msg.iEventParams.iExtra);
       
   418 				break;
       
   419 				}				
       
   420 			default:
       
   421 				{
       
   422 				// This is an invalid state
       
   423 				ASSERT(EFalse);
       
   424 				}					
       
   425 			};
       
   426 		}
       
   427 
       
   428 	// setup for next callbacks		
       
   429 	iStatus = KRequestPending;
       
   430 	iMsgQueue.NotifyDataAvailable(iStatus);
       
   431 	SetActive();	
       
   432 	}
       
   433 	
       
   434 COmxCallbacks::~COmxCallbacks()
       
   435 	{
       
   436 	Cancel();	
       
   437 	iMsgQueue.Close();
       
   438 	}
       
   439 	
       
   440 	
       
   441 void COmxCallbacks::DoCancel()
       
   442 	{
       
   443 	if (iMsgQueue.Handle()!=NULL)
       
   444 		{
       
   445 		iMsgQueue.CancelDataAvailable();
       
   446 		}
       
   447 	}
       
   448 	
       
   449 TInt COmxCallbacks::FillBufferDone(OMX_HANDLETYPE aComponent, COmxBufferManager::COmxBuffer* aBuffer)
       
   450 	{
       
   451 	TOmxMessage message;
       
   452 	message.iType = EFillBufferCallback;
       
   453 	message.iComponent = aComponent;
       
   454 	message.iBuffer = aBuffer;
       
   455 	return iMsgQueue.Send(message);
       
   456 	}
       
   457 	
       
   458 TInt COmxCallbacks::EmptyBufferDone(OMX_HANDLETYPE aComponent, COmxBufferManager::COmxBuffer* aBuffer)
       
   459 	{
       
   460 	TOmxMessage message;
       
   461 	message.iType = EEmptyBufferCallback;
       
   462 	message.iComponent = aComponent;
       
   463 	message.iBuffer = aBuffer;
       
   464 	return iMsgQueue.Send(message);
       
   465 	}
       
   466 	
       
   467 TInt COmxCallbacks::EventHandler(OMX_HANDLETYPE aComponent, TEventParams aEventParams)
       
   468 	{
       
   469 	TOmxMessage message;
       
   470 	message.iType = EEventCallback;
       
   471 	message.iComponent = aComponent;
       
   472 	message.iEventParams = aEventParams;
       
   473 	return iMsgQueue.Send(message);
       
   474 	}
       
   475 
       
   476 
       
   477  COmxProcessingUnit::CBody::CBody()
       
   478 	{
       
   479 	iPuState = EProcessingUnitInvalid;
       
   480 	}
       
   481 
       
   482 
       
   483 COmxProcessingUnit::CBody::~CBody()
       
   484 	{
       
   485 	delete iBufferManager;
       
   486 	delete iCallbacks;
       
   487 	
       
   488 	iInputPorts.Close();
       
   489 	iOutputPorts.Close();
       
   490 
       
   491 	::OMX_FreeHandle((OMX_HANDLETYPE)iHandle);
       
   492 	}
       
   493 
       
   494 COmxProcessingUnit::CBody* COmxProcessingUnit::CBody::NewL(const TDesC8& aComponentName, 
       
   495 															MOmxPuCallbacks& aPuCallbacks, 
       
   496 															COmxProcessingUnit* aParent,
       
   497 															const MMdfProcessingUnitObserver& aObserver)
       
   498 	{
       
   499 	CBody* self = new (ELeave) CBody;
       
   500 	CleanupStack::PushL(self);
       
   501 	self->ConstructL(aComponentName, aPuCallbacks, aParent, aObserver);
       
   502 	CleanupStack::Pop(self);
       
   503 	return self;
       
   504 	}
       
   505 	
       
   506 	
       
   507 void COmxProcessingUnit::CBody::ConstructL(const TDesC8& aComponentName, 
       
   508 											MOmxPuCallbacks& aPuCallbacks, 
       
   509 											COmxProcessingUnit* aParent,
       
   510 											const MMdfProcessingUnitObserver& aObserver)
       
   511 	{
       
   512 	iCallbacks = COmxCallbacks::NewL(aPuCallbacks);
       
   513 	
       
   514 	iParent = aParent;
       
   515 	iObserver = const_cast<MMdfProcessingUnitObserver*>(&aObserver);
       
   516 
       
   517 	OMX_ERRORTYPE errorType;
       
   518 	OMX_CALLBACKTYPE* omxCallbacks = *iCallbacks;
       
   519 	TBuf8<KMaxComponentNameLength> buf;
       
   520 	buf.Copy(aComponentName);
       
   521 	const char* name = reinterpret_cast<const char*>(buf.PtrZ());
       
   522 	errorType = ::OMX_GetHandle((OMX_HANDLETYPE*)&iHandle, const_cast<char*>(name), iCallbacks, omxCallbacks);
       
   523 
       
   524 	User::LeaveIfError(ConvertOmxErrorType(errorType));
       
   525 	// Create the BufferManager class to look after the buffering
       
   526 	iBufferManager = new (ELeave) COmxBufferManager(iHandle);
       
   527 	SetPuState(EProcessingUnitLoaded);
       
   528 	}
       
   529 
       
   530 
       
   531 
       
   532 TInt COmxProcessingUnit::CBody::GetInputPorts(RPointerArray<MMdfInputPort>& aComponentInputPorts)
       
   533 	{
       
   534 	TInt err = KErrNone;
       
   535 	for (TInt i=0; i < iInputPorts.Count() && err == KErrNone; i++ )
       
   536 		{
       
   537 		err = aComponentInputPorts.Append(iInputPorts[i]);
       
   538 		}
       
   539 	return err;
       
   540 	}
       
   541 
       
   542 
       
   543 TInt COmxProcessingUnit::CBody::GetOutputPorts(RPointerArray<MMdfOutputPort>& aComponentOutputPorts)
       
   544 	{
       
   545 	TInt err = KErrNone;
       
   546 	for (TInt i=0; i < iOutputPorts.Count() && err == KErrNone; i++ )
       
   547 		{
       
   548 		err = aComponentOutputPorts.Append(iOutputPorts[i]);
       
   549 		}
       
   550 	return err;
       
   551 	}
       
   552 	
       
   553 
       
   554 void COmxProcessingUnit::CBody::Initialize()
       
   555 	{
       
   556 	// if the state is not Loaded, we should not accept this call
       
   557 	if (State() != EProcessingUnitLoaded)
       
   558 		{	
       
   559 		Observer()->InitializeComplete(iParent, KErrNotReady); 
       
   560 		}
       
   561 	else
       
   562 		{
       
   563 		// initialize each of the ports in turn		
       
   564 		for (TInt i=0; i < iInputPorts.Count(); i++ )
       
   565 			{
       
   566 			iInputPorts[i]->MipInitialize();
       
   567 			}
       
   568 		
       
   569 	for (TInt i=0; i < iOutputPorts.Count(); i++ )
       
   570 		{
       
   571 		iOutputPorts[i]->MopInitialize();
       
   572 		}
       
   573 
       
   574 		// instruct the OMX component to go into the Idle state
       
   575 		SendCommand(OMX_CommandStateSet, OMX_StateIdle, NULL);
       
   576 		SetPuState(EProcessingUnitInitializing);
       
   577 		}	
       
   578 	}
       
   579 
       
   580 void COmxProcessingUnit::CBody::Execute()
       
   581 	{
       
   582 	
       
   583 	SendCommand(OMX_CommandStateSet, OMX_StateExecuting, NULL);
       
   584 	iPuState = EProcessingUnitExecuting;
       
   585 	}
       
   586 		
       
   587 TProcessingUnitState COmxProcessingUnit::CBody::State()
       
   588 	{
       
   589 	return iPuState;
       
   590 	}
       
   591 	
       
   592 TInt COmxProcessingUnit::CBody::EventHandler(OMX_HANDLETYPE /*aComponent*/, OMX_EVENTTYPE aEvent, TUint32 /*aData1*/,
       
   593 		 TUint32 aData2, TAny* /*aExtraInfo*/)
       
   594 	{	
       
   595 	switch (aEvent)
       
   596 		{
       
   597 		
       
   598 		case OMX_EventCmdComplete:
       
   599 			{
       
   600 		
       
   601 			switch (aData2)
       
   602 				{
       
   603 				case OMX_StateIdle:
       
   604 					if (iPuState == EProcessingUnitInitializing)
       
   605 						{
       
   606 						Observer()->InitializeComplete(iParent, KErrNone);
       
   607 						}
       
   608 					else
       
   609 						{
       
   610 						Observer()->ExecuteComplete(iParent, KErrNone);
       
   611 						}
       
   612 					SetPuState(EProcessingUnitIdle);
       
   613 					
       
   614 					break;
       
   615 				};
       
   616 			break;
       
   617 			}
       
   618 		case OMX_EventBufferFlag:
       
   619 			{
       
   620 			SendCommand(OMX_CommandStateSet, OMX_StateIdle, NULL);
       
   621 			}
       
   622 		}
       
   623 	return KErrNone;
       
   624 	}
       
   625 
       
   626 // Base Versions are not supported
       
   627 TInt COmxProcessingUnit::CBody::Configure(const TPuConfig& /*aConfig*/)
       
   628 	{
       
   629 	return KErrNotSupported;
       
   630 	}
       
   631 
       
   632 	
       
   633 // Base Versions are not supported
       
   634 TInt COmxProcessingUnit::CBody::GetConfig(TPuConfig& /*aConfig*/)
       
   635 	{
       
   636 	return KErrNotSupported;
       
   637 	}
       
   638 
       
   639 
       
   640 TInt COmxProcessingUnit::CBody::Pause ()
       
   641 	{
       
   642 	return KErrNone;
       
   643 	}
       
   644 
       
   645 void COmxProcessingUnit::CBody::Stop()
       
   646 	{
       
   647 	SendCommand(OMX_CommandStateSet, OMX_StateIdle, NULL);	
       
   648 	
       
   649 	TInt err = KErrNone;
       
   650 	for (TInt i=0; i < iInputPorts.Count() && err == KErrNone; i++ )
       
   651 		{
       
   652 		iInputPorts[i]->MipDisconnectTunnel();
       
   653 		}
       
   654 
       
   655 	for (TInt i=0; i < iOutputPorts.Count() && err == KErrNone; i++ )
       
   656 		{
       
   657 		iOutputPorts[i]->MopDisconnectTunnel();
       
   658 		}
       
   659 
       
   660 	SetPuState(EProcessingUnitIdle);	
       
   661 	}
       
   662 
       
   663 TInt COmxProcessingUnit::CBody::CreateCustomInterface(TUid /*aUid*/)
       
   664 	{
       
   665 	return KErrNotSupported;
       
   666 	}
       
   667 
       
   668 
       
   669 TAny* COmxProcessingUnit::CBody::CustomInterface(TUid /*aUid*/)
       
   670 	{
       
   671  	return NULL;
       
   672 	}
       
   673 	
       
   674 TInt COmxProcessingUnit::CBody::AddInputPort(MMdfInputPort* aInputPort)
       
   675 	{
       
   676 	if (iInputPorts.Find(aInputPort)>=0)
       
   677 		return KErrAlreadyExists;
       
   678 	return iInputPorts.Append(aInputPort);
       
   679 	}
       
   680 	
       
   681 TInt COmxProcessingUnit::CBody::AddOutputPort(MMdfOutputPort* aOutputPort)
       
   682 	{
       
   683 	if (iOutputPorts.Find(aOutputPort)>=0)
       
   684 		return KErrAlreadyExists;
       
   685 	return iOutputPorts.Append(aOutputPort);
       
   686 	}
       
   687 	
       
   688 MMdfProcessingUnitObserver* COmxProcessingUnit::CBody::Observer()
       
   689 	{
       
   690 	return iObserver;
       
   691 	}
       
   692 	
       
   693 void COmxProcessingUnit::CBody::SetPuState(TProcessingUnitState aPuState)
       
   694 	{
       
   695 	iPuState = aPuState;
       
   696 	}
       
   697 
       
   698 TInt COmxProcessingUnit::CBody::GetComponentVersion(const TDesC8& /*aComponentName*/, OMX_VERSIONTYPE* /*aComponentVersion*/, OMX_VERSIONTYPE* /*aSpecVersion*/, OMX_UUIDTYPE* /*aComponentUUID*/)
       
   699 	{
       
   700 	return KErrNotSupported;
       
   701 	}
       
   702 
       
   703 TInt COmxProcessingUnit::CBody::SendCommand(OMX_COMMANDTYPE aCmd, TUint aParam, TAny* aCmdData)
       
   704 	{
       
   705 	OMX_ERRORTYPE error = iHandle->SendCommand(static_cast<OMX_HANDLETYPE>(iHandle), aCmd, aParam, aCmdData);
       
   706 	return ConvertOmxErrorType(error);
       
   707 	}
       
   708 
       
   709 
       
   710 TInt COmxProcessingUnit::CBody::GetParameter(OMX_INDEXTYPE aParamIndex, TAny* aComponentParameterStructure)
       
   711 	{
       
   712 	OMX_ERRORTYPE error = iHandle->GetParameter(static_cast<OMX_HANDLETYPE>(iHandle), aParamIndex, aComponentParameterStructure);
       
   713 	return ConvertOmxErrorType(error);
       
   714 	}
       
   715 
       
   716 
       
   717 TInt COmxProcessingUnit::CBody::SetParameter(OMX_INDEXTYPE aIndex, TAny* aComponentParameterStructure)
       
   718 	{
       
   719 	OMX_ERRORTYPE error = iHandle->SetParameter(static_cast<OMX_HANDLETYPE>(iHandle), aIndex, aComponentParameterStructure);
       
   720 	return ConvertOmxErrorType(error);
       
   721 	}
       
   722 
       
   723 TInt COmxProcessingUnit::CBody::GetConfig(OMX_INDEXTYPE aIndex, TAny* aValue)
       
   724 	{
       
   725 	OMX_ERRORTYPE error = iHandle->GetConfig(static_cast<OMX_HANDLETYPE>(iHandle), aIndex, aValue);
       
   726 	return ConvertOmxErrorType(error);
       
   727 	}
       
   728 
       
   729 TInt COmxProcessingUnit::CBody::SetConfig(OMX_INDEXTYPE aIndex, TAny* aValue)
       
   730 	{
       
   731 	OMX_ERRORTYPE error = iHandle->SetConfig(static_cast<OMX_HANDLETYPE>(iHandle), aIndex, aValue);
       
   732 	return ConvertOmxErrorType(error);
       
   733 	}
       
   734 
       
   735 TInt COmxProcessingUnit::CBody::GetExtensionIndex(const TDesC8& aParameterName, OMX_INDEXTYPE* aIndexType)
       
   736 	{
       
   737 	HBufC8* buf = HBufC8::New(aParameterName.Length()+1);
       
   738 	if (buf == NULL)
       
   739 		{
       
   740 		return KErrNoMemory;
       
   741 		}
       
   742 	else
       
   743 		{
       
   744 		// Create a zero terminated version of the paramter name
       
   745 		*buf = aParameterName;
       
   746 		TPtr8 ptr = buf->Des();
       
   747 		TUint8* cstring = const_cast<TUint8*>(ptr.PtrZ());
       
   748 		OMX_ERRORTYPE error = iHandle->GetExtensionIndex(static_cast<OMX_HANDLETYPE>(iHandle), reinterpret_cast<char*>(cstring), aIndexType);
       
   749 		// delete the created memory - note no leaving functions so CleanupStack not used
       
   750 		delete buf;
       
   751 		return ConvertOmxErrorType(error);
       
   752 		}
       
   753 	}
       
   754 
       
   755 
       
   756 TInt COmxProcessingUnit::CBody::GetState(OMX_STATETYPE* aState)
       
   757 	{
       
   758 	OMX_ERRORTYPE error = iHandle->GetState(static_cast<OMX_HANDLETYPE>(iHandle), aState);
       
   759 	return ConvertOmxErrorType(error);
       
   760 	}
       
   761 
       
   762 
       
   763 TInt COmxProcessingUnit::CBody::ComponentTunnelRequest(TUint aPortInput, OMX_HANDLETYPE aOutput, TUint aPortOutput, OMX_TUNNELSETUPTYPE* aTunnelSetup)
       
   764 	{
       
   765 	OMX_ERRORTYPE error = iHandle->ComponentTunnelRequest(static_cast<OMX_HANDLETYPE>(iHandle), aPortInput, aOutput, aPortOutput, aTunnelSetup);
       
   766 	return ConvertOmxErrorType(error);
       
   767 	}
       
   768 	
       
   769 TInt COmxProcessingUnit::CBody::UseBuffer(CMMFBuffer* aBuffer, TUint aPortIndex)
       
   770 	{
       
   771 	return iBufferManager->UseBuffer(*aBuffer, aPortIndex);	
       
   772 	}
       
   773 
       
   774 
       
   775 CMMFBuffer* COmxProcessingUnit::CBody::AllocateBufferL(TUint aPortIndex, TUint aSizeBytes)
       
   776 	{
       
   777 	return iBufferManager->AllocateBufferL(aPortIndex, aSizeBytes);
       
   778 	}
       
   779 	
       
   780 
       
   781 TInt COmxProcessingUnit::CBody::FreeBuffer(CMMFBuffer* aBuffer)
       
   782 	{
       
   783 	return iBufferManager->FreeBuffer(aBuffer);
       
   784 	}
       
   785 
       
   786 TInt COmxProcessingUnit::CBody::EmptyThisBuffer(const CMMFBuffer* aBuffer, MOmxInputPortCallbacks* aObserver)
       
   787 	{
       
   788 	return iBufferManager->EmptyThisBuffer(aBuffer, aObserver);
       
   789 	}
       
   790 
       
   791 
       
   792 TInt COmxProcessingUnit::CBody::FillThisBuffer(CMMFBuffer* aBuffer, MOmxOutputPortCallbacks* aObserver)
       
   793 	{
       
   794 	return iBufferManager->FillThisBuffer(aBuffer, aObserver);
       
   795 	}
       
   796 
       
   797 
       
   798 TInt COmxProcessingUnit::CBody::SetCallbacks(MOmxPuCallbacks& /*aPuCallbacks*/)
       
   799 	{
       
   800 	return KErrNotSupported;
       
   801 	}
       
   802 
       
   803 // Callbacks implementation - calls back to COMxCallbacks class, which manages a queue
       
   804 OMX_ERRORTYPE EventHandler(OMX_OUT OMX_HANDLETYPE aComponent, 
       
   805 					OMX_OUT TAny* aAppData,
       
   806         			OMX_OUT OMX_EVENTTYPE aEvent, 
       
   807         			OMX_OUT TUint32 aData1,
       
   808         			OMX_OUT TUint32 aData2,
       
   809         			OMX_OUT TAny* aExtra)
       
   810 	{
       
   811 	COmxCallbacks::TEventParams eventParams;
       
   812 	eventParams.iEvent = aEvent;
       
   813 	eventParams.iData1 = aData1;
       
   814 	eventParams.iData2 = aData2;
       
   815 	eventParams.iExtra = aExtra;
       
   816 	TInt error = static_cast<COmxCallbacks*>(aAppData)->EventHandler(aComponent, eventParams);
       
   817 	return ConvertSymbianErrorType(error);
       
   818 	}
       
   819         			
       
   820 OMX_ERRORTYPE EmptyBufferDone(
       
   821        OMX_HANDLETYPE aComponent,
       
   822        TAny* aAppData,
       
   823        OMX_BUFFERHEADERTYPE* aBuffer)
       
   824 	{
       
   825 	COmxBufferManager::COmxBuffer* buffer = static_cast<COmxBufferManager::COmxBuffer*>(aBuffer->pAppPrivate);
       
   826 	TInt error = static_cast<COmxCallbacks*>(aAppData)->EmptyBufferDone(aComponent, buffer);
       
   827 	return ConvertSymbianErrorType(error);
       
   828 	}
       
   829         
       
   830 OMX_ERRORTYPE FillBufferDone(
       
   831        OMX_HANDLETYPE aComponent,
       
   832        TAny* aAppData,
       
   833        OMX_BUFFERHEADERTYPE* aBuffer)
       
   834 	{
       
   835 	COmxBufferManager::COmxBuffer* buffer = static_cast<COmxBufferManager::COmxBuffer*>(aBuffer->pAppPrivate);
       
   836 	TInt error = static_cast<COmxCallbacks*>(aAppData)->FillBufferDone(aComponent, buffer);
       
   837 	return ConvertSymbianErrorType(error);
       
   838 	}
       
   839