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