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