os/mm/mmdevicefw/mdf/src/audio/HwDeviceAdapter/mdfhwdeviceadapter.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
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 "HwDeviceAdapter/mdfhwdeviceadapter.h"
sl@0
    17
#include <mdf/codecapiuids.hrh>
sl@0
    18
#include <mdf/mdfpuconfig.h>
sl@0
    19
#include <mmf/server/devsoundstandardcustominterfaces.h>
sl@0
    20
sl@0
    21
// Interface UID for the Sink Processing Unit
sl@0
    22
const TUid KUidSourceSinkPu = {0x102730BB};
sl@0
    23
const TInt KZerothPort = 0;
sl@0
    24
sl@0
    25
/*
sl@0
    26
The destructor.  Unloads the Processing Units, deletes the 
sl@0
    27
Processing Unit Loader and frees any owned buffers.
sl@0
    28
@see CMMFHwDevice::~CMMFHwDevice()
sl@0
    29
*/
sl@0
    30
CMdfHwDeviceAdapter::~CMdfHwDeviceAdapter()
sl@0
    31
	{
sl@0
    32
	Stop();
sl@0
    33
	// Unload the PUs
sl@0
    34
	if (iCodecPU)
sl@0
    35
		{
sl@0
    36
		iPuLoader->UnloadProcessingUnit(iCodecPU);
sl@0
    37
		}
sl@0
    38
	if (iAudioDevicePU)
sl@0
    39
		{
sl@0
    40
		iPuLoader->UnloadProcessingUnit(iAudioDevicePU);
sl@0
    41
		}
sl@0
    42
	
sl@0
    43
	delete iInputBuffer;
sl@0
    44
	delete iOutputBuffer;		
sl@0
    45
	delete iActiveWait;
sl@0
    46
	delete iPuLoader;	
sl@0
    47
	REComSession::DestroyedImplementation(iPuLoaderDtorKey);
sl@0
    48
	}
sl@0
    49
sl@0
    50
/*
sl@0
    51
Creates a new CMdfHwDeviceAdapter object.  The Processing Unit Loader plugin
sl@0
    52
is also loaded, and so the CMdfHwDeviceAdapter state is set to EProcessingUnitLoaderLoaded.
sl@0
    53
Will leave with KErrNotFound if it, or the Processing Unit Loader plugin is not found.
sl@0
    54
@see THwDevAdapterState
sl@0
    55
*/
sl@0
    56
CMdfHwDeviceAdapter* CMdfHwDeviceAdapter::NewL()
sl@0
    57
	{
sl@0
    58
	CMdfHwDeviceAdapter* self = new (ELeave) CMdfHwDeviceAdapter;
sl@0
    59
	CleanupStack::PushL (self);
sl@0
    60
	self->ConstructL();
sl@0
    61
	CleanupStack::Pop(self);
sl@0
    62
	return self;
sl@0
    63
	}
sl@0
    64
sl@0
    65
/*
sl@0
    66
Default constructor.
sl@0
    67
*/	
sl@0
    68
CMdfHwDeviceAdapter::CMdfHwDeviceAdapter()
sl@0
    69
	{	
sl@0
    70
	}
sl@0
    71
sl@0
    72
/*
sl@0
    73
Loads the Processing Unit Loader plugin.
sl@0
    74
*/	
sl@0
    75
void CMdfHwDeviceAdapter::ConstructL()
sl@0
    76
	{		
sl@0
    77
	// Load the PU Loader plugin
sl@0
    78
	iPuLoader = static_cast<CMdfPuLoader*>
sl@0
    79
		(REComSession::CreateImplementationL(TUid::Uid(KUidPuLoaderImplementation), iPuLoaderDtorKey));
sl@0
    80
	iActiveWait = new (ELeave) CActiveSchedulerWait;
sl@0
    81
	iState = EProcessingUnitLoaderLoaded;
sl@0
    82
	}	
sl@0
    83
sl@0
    84
/*
sl@0
    85
@see CMMFHwDevice::Start()
sl@0
    86
@see TDeviceFunc
sl@0
    87
*/
sl@0
    88
TInt CMdfHwDeviceAdapter::Start(TDeviceFunc aFuncCmd, TDeviceFlow /*aFlowCmd*/)
sl@0
    89
	{		
sl@0
    90
	if (!((aFuncCmd == EDevEncode)|(aFuncCmd == EDevDecode)|(aFuncCmd == EDevNullFunc)))
sl@0
    91
		{
sl@0
    92
		return KErrArgument;	
sl@0
    93
		}
sl@0
    94
		
sl@0
    95
	iFuncCmd = aFuncCmd;
sl@0
    96
			
sl@0
    97
	TInt err = KErrNone;
sl@0
    98
	switch(aFuncCmd)
sl@0
    99
		{
sl@0
   100
		case EDevEncode:
sl@0
   101
			{
sl@0
   102
			err = StartEncode();
sl@0
   103
			}
sl@0
   104
			break;
sl@0
   105
		case EDevDecode:
sl@0
   106
			{
sl@0
   107
			err = StartDecode();
sl@0
   108
			}
sl@0
   109
			break;
sl@0
   110
		case EDevNullFunc:
sl@0
   111
			{
sl@0
   112
			// nothing at the moment, so fall through
sl@0
   113
			}
sl@0
   114
			//break;
sl@0
   115
		default:
sl@0
   116
			{
sl@0
   117
			err = KErrNotSupported;	
sl@0
   118
			}		
sl@0
   119
			break;
sl@0
   120
		}
sl@0
   121
sl@0
   122
	
sl@0
   123
	return err;
sl@0
   124
	}
sl@0
   125
	
sl@0
   126
/*
sl@0
   127
Initialises the encode operation, and set the state of the CMdfHwDeviceAdapter
sl@0
   128
to EProcessingUnitInitializing.
sl@0
   129
@return  An error code indicating if the function call was successful.
sl@0
   130
KErrNone on success, otherwise another of the system-wide error codes.
sl@0
   131
*/	
sl@0
   132
TInt CMdfHwDeviceAdapter::InitializeEncode()
sl@0
   133
	{
sl@0
   134
	ASSERT(iCodecOutputPort && iSourceOutputPort);
sl@0
   135
	// Create input buffer that passes data from Source -> Codec PU	
sl@0
   136
	TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iSourceOutputPort->MopBufferSize()));
sl@0
   137
	if(err != KErrNone)
sl@0
   138
		{
sl@0
   139
		return err;
sl@0
   140
		}
sl@0
   141
	
sl@0
   142
	// Create output buffer that passes decoded data from Codec PU -> Out to file	
sl@0
   143
	TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iCodecOutputPort->MopBufferSize()));
sl@0
   144
	if(err != KErrNone)
sl@0
   145
		{
sl@0
   146
		return err;
sl@0
   147
		}
sl@0
   148
	
sl@0
   149
	err = iSourceOutputPort->MopUseBuffer(*iInputBuffer);
sl@0
   150
	if(err != KErrNone)
sl@0
   151
		{
sl@0
   152
		return err;
sl@0
   153
		}		
sl@0
   154
	err = iCodecInputPort->MipUseBuffer(*iInputBuffer);
sl@0
   155
	if(err != KErrNone)
sl@0
   156
		{
sl@0
   157
		return err;
sl@0
   158
		}		
sl@0
   159
	err = iCodecOutputPort->MopUseBuffer(*iOutputBuffer);
sl@0
   160
	if(err != KErrNone)
sl@0
   161
		{
sl@0
   162
		return err;
sl@0
   163
		}
sl@0
   164
			
sl@0
   165
	// async calls, that callback to InitializeComplete()
sl@0
   166
	iCodecPU->Initialize();
sl@0
   167
	iAudioDevicePU->Initialize();
sl@0
   168
	if (iState == EProcessingUnitLoaded)
sl@0
   169
		{
sl@0
   170
		// only wait for the callbacks if we haven't already received them
sl@0
   171
		iState = EProcessingUnitInitializing;
sl@0
   172
		iActiveWait->Start();
sl@0
   173
		}
sl@0
   174
	return iInitError;
sl@0
   175
	}
sl@0
   176
	
sl@0
   177
/*
sl@0
   178
Starts the encode operation, providing that the intial state of the
sl@0
   179
CMdfHwDeviceAdapter is EProcessingUnitLoaded.
sl@0
   180
@return  An error code indicating if the function call was successful.
sl@0
   181
KErrNone on success, otherwise another of the system-wide error codes.
sl@0
   182
*/
sl@0
   183
TInt CMdfHwDeviceAdapter::StartEncode()
sl@0
   184
	{
sl@0
   185
	TInt err = KErrNone;
sl@0
   186
	if (iState == EProcessingUnitLoaded)
sl@0
   187
		{
sl@0
   188
		err = InitializeEncode();
sl@0
   189
		}
sl@0
   190
	if (err != KErrNone)
sl@0
   191
		{
sl@0
   192
		return err;
sl@0
   193
		}	
sl@0
   194
	if (iState == EProcessingUnitPaused)
sl@0
   195
		{
sl@0
   196
		// Ensure that the LastBuffer flags are reset.
sl@0
   197
		iInputBuffer->SetLastBuffer(EFalse);
sl@0
   198
		iOutputBuffer->SetLastBuffer(EFalse);
sl@0
   199
		}
sl@0
   200
					
sl@0
   201
	return StartExecuting();
sl@0
   202
	}
sl@0
   203
sl@0
   204
/*
sl@0
   205
Starts the execution of the encode or decode operation, and sets the state
sl@0
   206
of the CMdfHwDeviceAdapter to EProcessingUnitExecuting.
sl@0
   207
@return  An error code indicating if the function call was successful.
sl@0
   208
KErrNone on success, otherwise another of the system-wide error codes.
sl@0
   209
*/	
sl@0
   210
TInt CMdfHwDeviceAdapter::StartExecuting()
sl@0
   211
	{
sl@0
   212
	TInt err = KErrNone;
sl@0
   213
	if(iFuncCmd == EDevDecode)
sl@0
   214
		{
sl@0
   215
		iCodecOutputPort->MopReadData(*iOutputBuffer);		
sl@0
   216
		err = iHwDeviceObserver->FillThisHwBuffer(*iInputBuffer);
sl@0
   217
		if(err != KErrNone)
sl@0
   218
			{
sl@0
   219
			return err;
sl@0
   220
			}
sl@0
   221
		}
sl@0
   222
	else // encode
sl@0
   223
		{
sl@0
   224
		iSourceOutputPort->MopReadData(*iInputBuffer);
sl@0
   225
		iCodecOutputPort->MopReadData(*iOutputBuffer);	
sl@0
   226
		}		
sl@0
   227
		
sl@0
   228
	iState = EProcessingUnitExecuting;
sl@0
   229
		
sl@0
   230
	iCodecPU->Execute();
sl@0
   231
	iAudioDevicePU->Execute();
sl@0
   232
	
sl@0
   233
	return err;
sl@0
   234
	}
sl@0
   235
	
sl@0
   236
/*
sl@0
   237
Initialises the decode operation, and set the state of the CMdfHwDeviceAdapter
sl@0
   238
to EProcessingUnitInitializing.
sl@0
   239
@return  An error code indicating if the function call was successful.
sl@0
   240
KErrNone on success, otherwise another of the system-wide error codes.
sl@0
   241
*/	
sl@0
   242
TInt CMdfHwDeviceAdapter::InitializeDecode()
sl@0
   243
	{
sl@0
   244
	ASSERT(iCodecOutputPort && iSinkInputPort);
sl@0
   245
	
sl@0
   246
	TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iCodecInputPort->MipBufferSize()));
sl@0
   247
	if(err != KErrNone)
sl@0
   248
		{
sl@0
   249
		return err;
sl@0
   250
		}
sl@0
   251
		
sl@0
   252
	iCodecInputPort->MipUseBuffer(*iInputBuffer);	
sl@0
   253
	TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iCodecOutputPort->MopBufferSize()));
sl@0
   254
	if(err != KErrNone)
sl@0
   255
		{
sl@0
   256
		return err;
sl@0
   257
		}	
sl@0
   258
sl@0
   259
	// Try to set up a tunnelbetween the output port of the PCM Pu 
sl@0
   260
	// and the input port of the Sink Pu	
sl@0
   261
	if (iPuLoader->TunnelSetup(*iCodecOutputPort, *iSinkInputPort) != KErrNone)
sl@0
   262
		{
sl@0
   263
		iSinkInputPort->MipUseBuffer(*iOutputBuffer);
sl@0
   264
		}
sl@0
   265
	iCodecOutputPort->MopUseBuffer(*iOutputBuffer);		
sl@0
   266
	
sl@0
   267
	// async calls, that callback to InitializeComplete()
sl@0
   268
	iCodecPU->Initialize();
sl@0
   269
	iAudioDevicePU->Initialize();
sl@0
   270
	iState = EProcessingUnitInitializing;
sl@0
   271
	iActiveWait->Start();
sl@0
   272
	return KErrNone;
sl@0
   273
	}
sl@0
   274
sl@0
   275
/*
sl@0
   276
Starts the decode operation, providing that the intial state of the
sl@0
   277
CMdfHwDeviceAdapter is EProcessingUnitLoaded.
sl@0
   278
@return  An error code indicating if the function call was successful.
sl@0
   279
KErrNone on success, otherwise another of the system-wide error codes.
sl@0
   280
*/
sl@0
   281
TInt CMdfHwDeviceAdapter::StartDecode()
sl@0
   282
	{	
sl@0
   283
	TInt err = KErrNone;
sl@0
   284
	if (iState == EProcessingUnitLoaded)
sl@0
   285
		{
sl@0
   286
		err = InitializeDecode();
sl@0
   287
		}
sl@0
   288
	if (err != KErrNone)
sl@0
   289
		{
sl@0
   290
		return err;
sl@0
   291
		}
sl@0
   292
	if (iState == EProcessingUnitIdle)
sl@0
   293
		{
sl@0
   294
		// Ensure that the LastBuffer flags are reset.
sl@0
   295
		iInputBuffer->SetLastBuffer(EFalse);
sl@0
   296
		iOutputBuffer->SetLastBuffer(EFalse);
sl@0
   297
		}
sl@0
   298
	return StartExecuting();	
sl@0
   299
	}
sl@0
   300
sl@0
   301
/*
sl@0
   302
@see CMMFHwDevice::Stop()
sl@0
   303
*/
sl@0
   304
TInt CMdfHwDeviceAdapter::Stop()
sl@0
   305
	{	
sl@0
   306
	if(iState == EProcessingUnitExecuting || iState == EProcessingUnitPaused)
sl@0
   307
		{			
sl@0
   308
		iStopping = ETrue; // is used as a guard in ExecuteComplete
sl@0
   309
		if(iAudioDevicePU)
sl@0
   310
			{
sl@0
   311
			iAudioDevicePU->Stop();	
sl@0
   312
			}
sl@0
   313
		if(iCodecPU)
sl@0
   314
			{
sl@0
   315
			iCodecPU->Stop();	
sl@0
   316
			}
sl@0
   317
				
sl@0
   318
		iPCMPUCallbackComplete = EFalse;
sl@0
   319
		iSourceSinkPUCallbackComplete = EFalse;
sl@0
   320
				
sl@0
   321
		iState = EProcessingUnitIdle;
sl@0
   322
		iStopping = EFalse;	
sl@0
   323
		}
sl@0
   324
	return KErrNone;		
sl@0
   325
	}
sl@0
   326
sl@0
   327
/*
sl@0
   328
@see CMMFHwDevice::Pause()
sl@0
   329
*/
sl@0
   330
TInt CMdfHwDeviceAdapter::Pause()
sl@0
   331
	{
sl@0
   332
	TInt err = KErrNone;
sl@0
   333
	if(iState != EProcessingUnitPaused)
sl@0
   334
		{
sl@0
   335
		if(iAudioDevicePU)
sl@0
   336
			{	
sl@0
   337
			err = iAudioDevicePU->Pause();	
sl@0
   338
			}
sl@0
   339
		iState = EProcessingUnitPaused;
sl@0
   340
		}	
sl@0
   341
	return err;	
sl@0
   342
	}
sl@0
   343
sl@0
   344
/*
sl@0
   345
@see CMMFHwDevice::Init()
sl@0
   346
*/
sl@0
   347
TInt CMdfHwDeviceAdapter::Init(THwDeviceInitParams& aDevInfo)
sl@0
   348
	{	
sl@0
   349
	if(!iCodecPU)
sl@0
   350
		{
sl@0
   351
		return KErrNotSupported;
sl@0
   352
		}
sl@0
   353
		
sl@0
   354
	// Not currently using any other members of aDevInfo, except the Observer
sl@0
   355
	// Set observer	
sl@0
   356
	if(!aDevInfo.iHwDeviceObserver)
sl@0
   357
		{
sl@0
   358
		return KErrArgument;
sl@0
   359
		}
sl@0
   360
	iHwDeviceObserver = aDevInfo.iHwDeviceObserver;
sl@0
   361
	
sl@0
   362
	RPointerArray<MMdfInputPort> inputPorts;
sl@0
   363
	// Get ports and set observers
sl@0
   364
	TInt err = iCodecPU->GetInputPorts(inputPorts);		
sl@0
   365
	if (err == KErrNone && inputPorts.Count() > 0)
sl@0
   366
		{
sl@0
   367
		iCodecInputPort = inputPorts[KZerothPort];
sl@0
   368
		iCodecInputPort->MipSetObserver(*this);
sl@0
   369
		}		
sl@0
   370
	inputPorts.Close();	
sl@0
   371
	if (err != KErrNone)
sl@0
   372
		{
sl@0
   373
		return err;
sl@0
   374
		}		
sl@0
   375
	if (!iCodecInputPort)
sl@0
   376
		{
sl@0
   377
		return KErrNotFound;
sl@0
   378
		}
sl@0
   379
sl@0
   380
	RPointerArray<MMdfOutputPort> outputPorts;
sl@0
   381
	// Get ports and set observers
sl@0
   382
	err = iCodecPU->GetOutputPorts(outputPorts);	
sl@0
   383
	if (err == KErrNone && outputPorts.Count() > 0)
sl@0
   384
		{
sl@0
   385
		iCodecOutputPort = outputPorts[KZerothPort];
sl@0
   386
		iCodecOutputPort->MopSetObserver(*this);
sl@0
   387
		}		
sl@0
   388
	outputPorts.Close();	
sl@0
   389
	if (err != KErrNone)
sl@0
   390
		{
sl@0
   391
		return err;
sl@0
   392
		}
sl@0
   393
	if (!iCodecOutputPort)
sl@0
   394
		{
sl@0
   395
		return KErrNotFound;
sl@0
   396
		}
sl@0
   397
	
sl@0
   398
	// Load SourceSink Pu	
sl@0
   399
	TRAP(err, iAudioDevicePU = iPuLoader->LoadProcessingUnitL(*this, KUidSourceSinkPu));
sl@0
   400
	if(err!=KErrNone)
sl@0
   401
		{
sl@0
   402
		return err;
sl@0
   403
		}		
sl@0
   404
sl@0
   405
	err = iAudioDevicePU->GetInputPorts(inputPorts);	
sl@0
   406
	if (err == KErrNone && inputPorts.Count() > 0)
sl@0
   407
		{
sl@0
   408
		iSinkInputPort = inputPorts[KZerothPort];
sl@0
   409
		iSinkInputPort->MipSetObserver(*this);
sl@0
   410
		}		
sl@0
   411
	inputPorts.Close();
sl@0
   412
	if (err != KErrNone)
sl@0
   413
		{
sl@0
   414
		return err;
sl@0
   415
		}
sl@0
   416
	if (!iSinkInputPort)
sl@0
   417
		{
sl@0
   418
		return KErrNotFound;
sl@0
   419
		}
sl@0
   420
sl@0
   421
	
sl@0
   422
	err = iAudioDevicePU->GetOutputPorts(outputPorts);	
sl@0
   423
	if (err == KErrNone && outputPorts.Count() > 0)
sl@0
   424
		{
sl@0
   425
		iSourceOutputPort = outputPorts[KZerothPort];
sl@0
   426
		iSourceOutputPort->MopSetObserver(*this);
sl@0
   427
		}		
sl@0
   428
	outputPorts.Close();
sl@0
   429
	if (err != KErrNone)
sl@0
   430
		{
sl@0
   431
		return err;
sl@0
   432
		}
sl@0
   433
	if (!iCodecOutputPort)
sl@0
   434
		{
sl@0
   435
		return KErrNotFound;
sl@0
   436
		}
sl@0
   437
	
sl@0
   438
	iState = EProcessingUnitLoaded;
sl@0
   439
	return KErrNone;		
sl@0
   440
	}
sl@0
   441
sl@0
   442
/*
sl@0
   443
@see CMMFHwDevice::CustomInterface()
sl@0
   444
*/
sl@0
   445
TAny* CMdfHwDeviceAdapter::CustomInterface(TUid aInterfaceId)
sl@0
   446
	{
sl@0
   447
	if (aInterfaceId == KUidHwDeviceSetupInterface)
sl@0
   448
		{
sl@0
   449
		MMdfHwDeviceSetup* hwDeviceSetup = this;
sl@0
   450
		return hwDeviceSetup;
sl@0
   451
		}
sl@0
   452
	else if (aInterfaceId.iUid == KMmfPlaySettingsCustomInterface)
sl@0
   453
		{
sl@0
   454
		return iSinkInputPort->MipCustomInterface(aInterfaceId);
sl@0
   455
		}
sl@0
   456
	else if (aInterfaceId.iUid == KMmfRecordSettingsCustomInterface)
sl@0
   457
		{
sl@0
   458
		return iSourceOutputPort->MopCustomInterface(aInterfaceId);
sl@0
   459
		}
sl@0
   460
	else if (aInterfaceId == KUidCustomInterfaceDevSoundBitRate)
sl@0
   461
		{
sl@0
   462
		return iCodecPU->CustomInterface(aInterfaceId);
sl@0
   463
		}
sl@0
   464
	else		
sl@0
   465
		{
sl@0
   466
		return NULL;
sl@0
   467
		}
sl@0
   468
	}
sl@0
   469
sl@0
   470
/*
sl@0
   471
@see CMMFHwDevice::ThisHwBufferFilled()
sl@0
   472
*/
sl@0
   473
TInt CMdfHwDeviceAdapter::ThisHwBufferFilled(CMMFBuffer& aFillBufferPtr)
sl@0
   474
	{
sl@0
   475
	aFillBufferPtr.SetStatus(EFull);	
sl@0
   476
	iCodecInputPort->MipWriteData(aFillBufferPtr);
sl@0
   477
	return KErrNone;
sl@0
   478
	}
sl@0
   479
sl@0
   480
/*
sl@0
   481
@see CMMFHwDevice::ThisHwBufferEmptied()
sl@0
   482
*/
sl@0
   483
TInt CMdfHwDeviceAdapter::ThisHwBufferEmptied(CMMFBuffer& /*aEmptyBufferPtr*/)
sl@0
   484
	{
sl@0
   485
	if (iOutputBuffer->LastBuffer())
sl@0
   486
		{
sl@0
   487
		CMMFDataBuffer* buffer = static_cast <CMMFDataBuffer*> (iOutputBuffer);
sl@0
   488
		buffer->Data().SetLength(0);
sl@0
   489
		iHwDeviceObserver->EmptyThisHwBuffer(*iOutputBuffer);
sl@0
   490
		}
sl@0
   491
	else	
sl@0
   492
		{
sl@0
   493
		iCodecOutputPort->MopReadData(*iOutputBuffer);
sl@0
   494
		}
sl@0
   495
	return KErrNone;
sl@0
   496
	}
sl@0
   497
sl@0
   498
/*
sl@0
   499
@see CMMFHwDevice::SetConfig()
sl@0
   500
*/
sl@0
   501
TInt CMdfHwDeviceAdapter::SetConfig(TTaskConfig& aConfig)
sl@0
   502
	{
sl@0
   503
	TInt err = KErrNone;
sl@0
   504
	// Call to Configure the Codec PU
sl@0
   505
	TPuTaskConfig config(aConfig);
sl@0
   506
	err = iCodecInputPort->MipConfigure(config);
sl@0
   507
	if(err != KErrNone)
sl@0
   508
		{
sl@0
   509
		return err;
sl@0
   510
		}
sl@0
   511
	err = iCodecOutputPort->MopConfigure(config);
sl@0
   512
	if(err != KErrNone)
sl@0
   513
		{
sl@0
   514
		return err;
sl@0
   515
		}
sl@0
   516
sl@0
   517
	// configure the audio device
sl@0
   518
	err = iSinkInputPort->MipConfigure(config);
sl@0
   519
	if(err != KErrNone)
sl@0
   520
		{
sl@0
   521
		return err;
sl@0
   522
		}
sl@0
   523
	err = iSourceOutputPort->MopConfigure(config);
sl@0
   524
	if(err != KErrNone)
sl@0
   525
		{
sl@0
   526
		return err;
sl@0
   527
		}
sl@0
   528
sl@0
   529
	return KErrNone;
sl@0
   530
	}
sl@0
   531
sl@0
   532
/*
sl@0
   533
@see CMMFHwDevice::StopAndDeleteCodec()
sl@0
   534
*/
sl@0
   535
TInt CMdfHwDeviceAdapter::StopAndDeleteCodec()
sl@0
   536
	{	
sl@0
   537
	TInt stopError = Stop();
sl@0
   538
	TInt deleteError = DeleteCodec();
sl@0
   539
sl@0
   540
	if (stopError != KErrNone)
sl@0
   541
		{
sl@0
   542
		return stopError;
sl@0
   543
		}		
sl@0
   544
	else
sl@0
   545
		{
sl@0
   546
		return deleteError;
sl@0
   547
		}		
sl@0
   548
	}
sl@0
   549
sl@0
   550
/*
sl@0
   551
Unloads all Processing Units, and deletes any locally owned buffers.
sl@0
   552
State is set to EProcessingUnitLoaderLoaded.
sl@0
   553
sl@0
   554
@see CMMFHwDevice::DeleteCodec()
sl@0
   555
*/
sl@0
   556
TInt CMdfHwDeviceAdapter::DeleteCodec()
sl@0
   557
	{
sl@0
   558
	Stop();	
sl@0
   559
	if (iCodecPU)
sl@0
   560
		{
sl@0
   561
		iPuLoader->UnloadProcessingUnit(iCodecPU);		
sl@0
   562
		}		
sl@0
   563
	if (iAudioDevicePU)	
sl@0
   564
		{
sl@0
   565
		iPuLoader->UnloadProcessingUnit(iAudioDevicePU);		
sl@0
   566
		}	
sl@0
   567
	
sl@0
   568
	// CMdfHwDeviceAdapter does not own the I/O ports, which 
sl@0
   569
	// have been deleted at this point by UnloadProcessingUnit()
sl@0
   570
	iCodecInputPort = NULL;
sl@0
   571
	iCodecOutputPort = NULL;
sl@0
   572
	iSinkInputPort = NULL;
sl@0
   573
	iSourceOutputPort = NULL;	
sl@0
   574
		
sl@0
   575
	delete iInputBuffer;
sl@0
   576
	iInputBuffer = NULL;
sl@0
   577
	delete iOutputBuffer;
sl@0
   578
	iOutputBuffer = NULL;
sl@0
   579
	
sl@0
   580
	iState = EProcessingUnitLoaderLoaded;
sl@0
   581
	
sl@0
   582
	return KErrNone;
sl@0
   583
	}
sl@0
   584
sl@0
   585
/*
sl@0
   586
@see MMdfInputPortObserver::MipoWriteDataComplete()
sl@0
   587
*/
sl@0
   588
void CMdfHwDeviceAdapter::MipoWriteDataComplete(const MMdfInputPort* aInputPort,
sl@0
   589
	CMMFBuffer* aBuffer, TInt aErrorCode)
sl@0
   590
	{
sl@0
   591
	if(aErrorCode != KErrNone)
sl@0
   592
		{
sl@0
   593
		StopHwDevice(aErrorCode);
sl@0
   594
		}
sl@0
   595
	else
sl@0
   596
		{
sl@0
   597
		switch(iFuncCmd)
sl@0
   598
			{
sl@0
   599
			case EDevEncode:
sl@0
   600
				{				
sl@0
   601
				if(aInputPort == iCodecInputPort)
sl@0
   602
					{
sl@0
   603
					if(aBuffer->LastBuffer())
sl@0
   604
						{
sl@0
   605
						iCodecPU->Stop();
sl@0
   606
						}
sl@0
   607
					else
sl@0
   608
						{
sl@0
   609
						// if not the last buffer, then pass buffer back to source to get more data				
sl@0
   610
						iSourceOutputPort->MopReadData(*iInputBuffer);
sl@0
   611
						}
sl@0
   612
					}
sl@0
   613
				}
sl@0
   614
				break;
sl@0
   615
			case EDevDecode:
sl@0
   616
				{
sl@0
   617
				if(aInputPort == iCodecInputPort)
sl@0
   618
					{				
sl@0
   619
					if (!aBuffer->LastBuffer())
sl@0
   620
						{	
sl@0
   621
						// JW 22-05-06
sl@0
   622
						// if the PU is idle (having been Stopped) then
sl@0
   623
						// FillThisHwBuffer will cause a kern-exec,
sl@0
   624
						// as the DevSoundSession no longer has a buffer
sl@0
   625
						if(iState == EProcessingUnitExecuting) 
sl@0
   626
							{
sl@0
   627
							TInt err = iHwDeviceObserver->FillThisHwBuffer(*aBuffer);
sl@0
   628
							if(err != KErrNone)
sl@0
   629
								{
sl@0
   630
								StopHwDevice(err);
sl@0
   631
								}						
sl@0
   632
							}
sl@0
   633
						}
sl@0
   634
					}
sl@0
   635
				else // aInputPort == iSinkInputPort
sl@0
   636
					{
sl@0
   637
					if (!aBuffer->LastBuffer())
sl@0
   638
						{				
sl@0
   639
						if(iSinkInputPort->MipIsTunnelled())
sl@0
   640
							{
sl@0
   641
							// This callback shouldn't occur since it should be tunnelled with the sink input port
sl@0
   642
							StopHwDevice(KErrArgument);
sl@0
   643
							}
sl@0
   644
						else
sl@0
   645
							{
sl@0
   646
							iCodecOutputPort->MopReadData(*iOutputBuffer);
sl@0
   647
							}
sl@0
   648
						}
sl@0
   649
					}
sl@0
   650
				}
sl@0
   651
				break;
sl@0
   652
			case EDevNullFunc:
sl@0
   653
				// nothing at the moment, so fall through
sl@0
   654
			default:
sl@0
   655
				StopHwDevice(KErrNotSupported);	
sl@0
   656
			}
sl@0
   657
		}
sl@0
   658
	}
sl@0
   659
sl@0
   660
/*
sl@0
   661
@see MMdfInputPortObserver::MipoDisconnectTunnelComplete()
sl@0
   662
*/	
sl@0
   663
void CMdfHwDeviceAdapter::MipoDisconnectTunnelComplete(const MMdfInputPort* aInputPort, 
sl@0
   664
	TInt aErrorCode)
sl@0
   665
	{
sl@0
   666
	// The Inputport of the PcmCodecPu will no longer receive data.	
sl@0
   667
	if(aErrorCode == KErrNone)
sl@0
   668
		{
sl@0
   669
		if(aInputPort == iCodecInputPort)
sl@0
   670
			{
sl@0
   671
			iPCMPuMipoStopCompleted = ETrue;
sl@0
   672
			}
sl@0
   673
		else if(aInputPort == iSinkInputPort)
sl@0
   674
			{
sl@0
   675
			// This shouldn't be called!
sl@0
   676
			iHwDeviceObserver->Error(KErrNotFound);		
sl@0
   677
			}
sl@0
   678
		}
sl@0
   679
	else
sl@0
   680
		{
sl@0
   681
		iHwDeviceObserver->Error(aErrorCode);
sl@0
   682
		}	
sl@0
   683
	}
sl@0
   684
sl@0
   685
/*
sl@0
   686
@see MMdfInputPortObserver::MipoRestartTunnelComplete()
sl@0
   687
*/
sl@0
   688
void CMdfHwDeviceAdapter::MipoRestartTunnelComplete(const MMdfInputPort* /*aInputPort*/,
sl@0
   689
	TInt /*aErrorCode*/)
sl@0
   690
	{
sl@0
   691
	
sl@0
   692
	}
sl@0
   693
	
sl@0
   694
/*
sl@0
   695
@see MMdfOutputPortObserver::MopoReadDataComplete()
sl@0
   696
*/
sl@0
   697
void CMdfHwDeviceAdapter::MopoReadDataComplete(const MMdfOutputPort* aOutputPort, 
sl@0
   698
	CMMFBuffer* aBuffer, TInt aErrorCode)
sl@0
   699
	{
sl@0
   700
	if(aErrorCode != KErrNone)
sl@0
   701
		{
sl@0
   702
		StopHwDevice(aErrorCode);
sl@0
   703
		}
sl@0
   704
	else
sl@0
   705
		{
sl@0
   706
		switch(iFuncCmd)
sl@0
   707
			{
sl@0
   708
			case EDevEncode:
sl@0
   709
				{
sl@0
   710
				if(aOutputPort == iSourceOutputPort)
sl@0
   711
					{
sl@0
   712
					iCodecInputPort->MipWriteData(*aBuffer);
sl@0
   713
					}
sl@0
   714
				else // aPu == iCodecPU
sl@0
   715
					{
sl@0
   716
					TInt err = iHwDeviceObserver->EmptyThisHwBuffer(*aBuffer);
sl@0
   717
					if(err !=KErrNone)
sl@0
   718
						{
sl@0
   719
						StopHwDevice(err);
sl@0
   720
						}
sl@0
   721
					}
sl@0
   722
				}
sl@0
   723
				break;
sl@0
   724
			case EDevDecode:
sl@0
   725
				{
sl@0
   726
				if(aOutputPort == iCodecOutputPort)
sl@0
   727
					{
sl@0
   728
					if(iCodecOutputPort->MopIsTunnelled())
sl@0
   729
						{
sl@0
   730
						// This callback shouldn't occur since it should be tunnelled with the sink input port
sl@0
   731
						StopHwDevice(KErrArgument);
sl@0
   732
						}
sl@0
   733
					else
sl@0
   734
						{
sl@0
   735
						iSinkInputPort->MipWriteData(*aBuffer);
sl@0
   736
						}
sl@0
   737
					}
sl@0
   738
				}
sl@0
   739
				break;
sl@0
   740
			case EDevNullFunc:
sl@0
   741
				// nothing at the moment, so fall through
sl@0
   742
			default:
sl@0
   743
				StopHwDevice(KErrNotSupported);
sl@0
   744
			}		
sl@0
   745
		}
sl@0
   746
	}
sl@0
   747
sl@0
   748
/*
sl@0
   749
@see MMdfOutputPortObserver::MopoDisconnectTunnelComplete()
sl@0
   750
*/	
sl@0
   751
void CMdfHwDeviceAdapter::MopoDisconnectTunnelComplete(const MMdfOutputPort* aOutputPort,
sl@0
   752
	TInt aErrorCode)
sl@0
   753
	{
sl@0
   754
	if(!aOutputPort)
sl@0
   755
		{
sl@0
   756
		iHwDeviceObserver->Error(KErrArgument);
sl@0
   757
		return;
sl@0
   758
		}		
sl@0
   759
		
sl@0
   760
	// The last buffer has been set, and called back to MopoReadDataComplete
sl@0
   761
	if(aErrorCode != KErrNone)
sl@0
   762
		{
sl@0
   763
		iHwDeviceObserver->Error(aErrorCode);
sl@0
   764
		return;
sl@0
   765
		}	
sl@0
   766
sl@0
   767
	if(aOutputPort == iCodecOutputPort)
sl@0
   768
		{		
sl@0
   769
		iPCMPuMopoStopCompleted = ETrue;	
sl@0
   770
		}
sl@0
   771
	else if(aOutputPort == iSourceOutputPort)
sl@0
   772
		{
sl@0
   773
		iSourceSinkPuMopoStopCompleted = ETrue;
sl@0
   774
		}
sl@0
   775
	else
sl@0
   776
		{
sl@0
   777
		iHwDeviceObserver->Error(KErrArgument);
sl@0
   778
		return;
sl@0
   779
		}
sl@0
   780
			
sl@0
   781
	if(iPCMPuMipoStopCompleted && iPCMPuMopoStopCompleted && iSourceSinkPuMopoStopCompleted)
sl@0
   782
		{
sl@0
   783
		iHwDeviceObserver->Error(KErrNone);
sl@0
   784
		iState = EProcessingUnitIdle;
sl@0
   785
		}		
sl@0
   786
	}
sl@0
   787
sl@0
   788
/*
sl@0
   789
@see MMdfOutputPortObserver::MopoRestartTunnelComplete()
sl@0
   790
*/	
sl@0
   791
void CMdfHwDeviceAdapter::MopoRestartTunnelComplete(const MMdfOutputPort* /*aOutputPort*/,
sl@0
   792
	TInt /*aErrorCode*/)
sl@0
   793
	{
sl@0
   794
	
sl@0
   795
	}
sl@0
   796
sl@0
   797
/*
sl@0
   798
@see MMdfProcessingUnitObserver::InitializeComplete()
sl@0
   799
*/
sl@0
   800
void CMdfHwDeviceAdapter::InitializeComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
sl@0
   801
	{
sl@0
   802
	iInitError = aErrorCode;
sl@0
   803
	if(aErrorCode != KErrNone)
sl@0
   804
		{
sl@0
   805
		// stop waiting on the active scheduler if we were doing so
sl@0
   806
		if (iState == EProcessingUnitInitializing)
sl@0
   807
			{
sl@0
   808
			// change state back to processing unit loaded
sl@0
   809
			iState = EProcessingUnitLoaded;
sl@0
   810
			iActiveWait->AsyncStop();
sl@0
   811
			}
sl@0
   812
		return;
sl@0
   813
		}
sl@0
   814
			
sl@0
   815
	if(aPu == iCodecPU)
sl@0
   816
		{
sl@0
   817
		iPCMPUCallbackComplete = ETrue;
sl@0
   818
		}
sl@0
   819
	else if(aPu == iAudioDevicePU)
sl@0
   820
		{
sl@0
   821
		iSourceSinkPUCallbackComplete = ETrue;
sl@0
   822
		}	
sl@0
   823
sl@0
   824
	if(iPCMPUCallbackComplete && iSourceSinkPUCallbackComplete)
sl@0
   825
		{
sl@0
   826
		// reset the flags
sl@0
   827
		iPCMPUCallbackComplete = EFalse;
sl@0
   828
		iSourceSinkPUCallbackComplete = EFalse;
sl@0
   829
		
sl@0
   830
		// Both PUs initialised OK
sl@0
   831
		if (iState == EProcessingUnitInitializing)
sl@0
   832
			{
sl@0
   833
			iActiveWait->AsyncStop();
sl@0
   834
			}
sl@0
   835
		iState = EProcessingUnitIdle;
sl@0
   836
		}
sl@0
   837
	}
sl@0
   838
sl@0
   839
/*
sl@0
   840
@see MMdfProcessingUnitObserver::ExecuteComplete()
sl@0
   841
*/
sl@0
   842
void CMdfHwDeviceAdapter::ExecuteComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
sl@0
   843
	{
sl@0
   844
	if(iStopping)
sl@0
   845
		{
sl@0
   846
		return;
sl@0
   847
		}
sl@0
   848
		
sl@0
   849
	if (iExecuteError == KErrNone)
sl@0
   850
		{
sl@0
   851
		iExecuteError = aErrorCode;
sl@0
   852
		}
sl@0
   853
	 		
sl@0
   854
	if(aPu == iCodecPU)
sl@0
   855
		{
sl@0
   856
		iPCMPUCallbackComplete = ETrue;
sl@0
   857
		}
sl@0
   858
	else if(aPu == iAudioDevicePU)
sl@0
   859
		{
sl@0
   860
		iSourceSinkPUCallbackComplete = ETrue;
sl@0
   861
		}	
sl@0
   862
sl@0
   863
	if(iExecuteError != KErrNone || (iPCMPUCallbackComplete && iSourceSinkPUCallbackComplete))
sl@0
   864
		{
sl@0
   865
		if (iState == EProcessingUnitExecuting)
sl@0
   866
			{
sl@0
   867
			// stop the hardware device if we are still executing
sl@0
   868
			StopHwDevice(iExecuteError);		
sl@0
   869
			iState = EProcessingUnitIdle;
sl@0
   870
			}
sl@0
   871
		// reset the flags
sl@0
   872
		iPCMPUCallbackComplete = EFalse;
sl@0
   873
		iSourceSinkPUCallbackComplete = EFalse;					
sl@0
   874
		}
sl@0
   875
	}
sl@0
   876
sl@0
   877
/*
sl@0
   878
@see MMdfHwDeviceSetup::::SetDataTypesL()
sl@0
   879
*/
sl@0
   880
void CMdfHwDeviceAdapter::SetDataTypesL(TFourCC aSrcType, TFourCC aDestType)
sl@0
   881
	{
sl@0
   882
	// Find and load an appropriate Codec
sl@0
   883
	iCodecPU = iPuLoader->LoadProcessingUnitL(*this, aSrcType, aDestType);
sl@0
   884
	}
sl@0
   885
sl@0
   886
/*
sl@0
   887
Called to indicate that the Hardware Device has been stopped, leading
sl@0
   888
to callbacks to the observer. 
sl@0
   889
@see MMMFHwDeviceObserver::Stopped()
sl@0
   890
@see MMMFHwDeviceObserver::Error()
sl@0
   891
*/
sl@0
   892
void CMdfHwDeviceAdapter::StopHwDevice(TInt error)
sl@0
   893
	{
sl@0
   894
	iHwDeviceObserver->Stopped();
sl@0
   895
	iHwDeviceObserver->Error(error);		
sl@0
   896
	}
sl@0
   897
sl@0
   898
/*
sl@0
   899
Returns the state of the Hardware Device Adapter object.
sl@0
   900
*/
sl@0
   901
void CMdfHwDeviceAdapter::GetState(THwDevAdapterState& aState) const
sl@0
   902
	{
sl@0
   903
	aState = iState;	
sl@0
   904
	}
sl@0
   905