mmdevicefw/mdf/src/audio/HwDeviceAdapter/mdfhwdeviceadapter.cpp
changeset 0 79dd3e2336a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmdevicefw/mdf/src/audio/HwDeviceAdapter/mdfhwdeviceadapter.cpp	Fri Oct 08 19:40:43 2010 +0100
@@ -0,0 +1,905 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "HwDeviceAdapter/mdfhwdeviceadapter.h"
+#include <mdf/codecapiuids.hrh>
+#include <mdf/mdfpuconfig.h>
+#include <mmf/server/devsoundstandardcustominterfaces.h>
+
+// Interface UID for the Sink Processing Unit
+const TUid KUidSourceSinkPu = {0x102730BB};
+const TInt KZerothPort = 0;
+
+/*
+The destructor.  Unloads the Processing Units, deletes the 
+Processing Unit Loader and frees any owned buffers.
+@see CMMFHwDevice::~CMMFHwDevice()
+*/
+CMdfHwDeviceAdapter::~CMdfHwDeviceAdapter()
+	{
+	Stop();
+	// Unload the PUs
+	if (iCodecPU)
+		{
+		iPuLoader->UnloadProcessingUnit(iCodecPU);
+		}
+	if (iAudioDevicePU)
+		{
+		iPuLoader->UnloadProcessingUnit(iAudioDevicePU);
+		}
+	
+	delete iInputBuffer;
+	delete iOutputBuffer;		
+	delete iActiveWait;
+	delete iPuLoader;	
+	REComSession::DestroyedImplementation(iPuLoaderDtorKey);
+	}
+
+/*
+Creates a new CMdfHwDeviceAdapter object.  The Processing Unit Loader plugin
+is also loaded, and so the CMdfHwDeviceAdapter state is set to EProcessingUnitLoaderLoaded.
+Will leave with KErrNotFound if it, or the Processing Unit Loader plugin is not found.
+@see THwDevAdapterState
+*/
+CMdfHwDeviceAdapter* CMdfHwDeviceAdapter::NewL()
+	{
+	CMdfHwDeviceAdapter* self = new (ELeave) CMdfHwDeviceAdapter;
+	CleanupStack::PushL (self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/*
+Default constructor.
+*/	
+CMdfHwDeviceAdapter::CMdfHwDeviceAdapter()
+	{	
+	}
+
+/*
+Loads the Processing Unit Loader plugin.
+*/	
+void CMdfHwDeviceAdapter::ConstructL()
+	{		
+	// Load the PU Loader plugin
+	iPuLoader = static_cast<CMdfPuLoader*>
+		(REComSession::CreateImplementationL(TUid::Uid(KUidPuLoaderImplementation), iPuLoaderDtorKey));
+	iActiveWait = new (ELeave) CActiveSchedulerWait;
+	iState = EProcessingUnitLoaderLoaded;
+	}	
+
+/*
+@see CMMFHwDevice::Start()
+@see TDeviceFunc
+*/
+TInt CMdfHwDeviceAdapter::Start(TDeviceFunc aFuncCmd, TDeviceFlow /*aFlowCmd*/)
+	{		
+	if (!((aFuncCmd == EDevEncode)|(aFuncCmd == EDevDecode)|(aFuncCmd == EDevNullFunc)))
+		{
+		return KErrArgument;	
+		}
+		
+	iFuncCmd = aFuncCmd;
+			
+	TInt err = KErrNone;
+	switch(aFuncCmd)
+		{
+		case EDevEncode:
+			{
+			err = StartEncode();
+			}
+			break;
+		case EDevDecode:
+			{
+			err = StartDecode();
+			}
+			break;
+		case EDevNullFunc:
+			{
+			// nothing at the moment, so fall through
+			}
+			//break;
+		default:
+			{
+			err = KErrNotSupported;	
+			}		
+			break;
+		}
+
+	
+	return err;
+	}
+	
+/*
+Initialises the encode operation, and set the state of the CMdfHwDeviceAdapter
+to EProcessingUnitInitializing.
+@return  An error code indicating if the function call was successful.
+KErrNone on success, otherwise another of the system-wide error codes.
+*/	
+TInt CMdfHwDeviceAdapter::InitializeEncode()
+	{
+	ASSERT(iCodecOutputPort && iSourceOutputPort);
+	// Create input buffer that passes data from Source -> Codec PU	
+	TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iSourceOutputPort->MopBufferSize()));
+	if(err != KErrNone)
+		{
+		return err;
+		}
+	
+	// Create output buffer that passes decoded data from Codec PU -> Out to file	
+	TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iCodecOutputPort->MopBufferSize()));
+	if(err != KErrNone)
+		{
+		return err;
+		}
+	
+	err = iSourceOutputPort->MopUseBuffer(*iInputBuffer);
+	if(err != KErrNone)
+		{
+		return err;
+		}		
+	err = iCodecInputPort->MipUseBuffer(*iInputBuffer);
+	if(err != KErrNone)
+		{
+		return err;
+		}		
+	err = iCodecOutputPort->MopUseBuffer(*iOutputBuffer);
+	if(err != KErrNone)
+		{
+		return err;
+		}
+			
+	// async calls, that callback to InitializeComplete()
+	iCodecPU->Initialize();
+	iAudioDevicePU->Initialize();
+	if (iState == EProcessingUnitLoaded)
+		{
+		// only wait for the callbacks if we haven't already received them
+		iState = EProcessingUnitInitializing;
+		iActiveWait->Start();
+		}
+	return iInitError;
+	}
+	
+/*
+Starts the encode operation, providing that the intial state of the
+CMdfHwDeviceAdapter is EProcessingUnitLoaded.
+@return  An error code indicating if the function call was successful.
+KErrNone on success, otherwise another of the system-wide error codes.
+*/
+TInt CMdfHwDeviceAdapter::StartEncode()
+	{
+	TInt err = KErrNone;
+	if (iState == EProcessingUnitLoaded)
+		{
+		err = InitializeEncode();
+		}
+	if (err != KErrNone)
+		{
+		return err;
+		}	
+	if (iState == EProcessingUnitPaused)
+		{
+		// Ensure that the LastBuffer flags are reset.
+		iInputBuffer->SetLastBuffer(EFalse);
+		iOutputBuffer->SetLastBuffer(EFalse);
+		}
+					
+	return StartExecuting();
+	}
+
+/*
+Starts the execution of the encode or decode operation, and sets the state
+of the CMdfHwDeviceAdapter to EProcessingUnitExecuting.
+@return  An error code indicating if the function call was successful.
+KErrNone on success, otherwise another of the system-wide error codes.
+*/	
+TInt CMdfHwDeviceAdapter::StartExecuting()
+	{
+	TInt err = KErrNone;
+	if(iFuncCmd == EDevDecode)
+		{
+		iCodecOutputPort->MopReadData(*iOutputBuffer);		
+		err = iHwDeviceObserver->FillThisHwBuffer(*iInputBuffer);
+		if(err != KErrNone)
+			{
+			return err;
+			}
+		}
+	else // encode
+		{
+		iSourceOutputPort->MopReadData(*iInputBuffer);
+		iCodecOutputPort->MopReadData(*iOutputBuffer);	
+		}		
+		
+	iState = EProcessingUnitExecuting;
+		
+	iCodecPU->Execute();
+	iAudioDevicePU->Execute();
+	
+	return err;
+	}
+	
+/*
+Initialises the decode operation, and set the state of the CMdfHwDeviceAdapter
+to EProcessingUnitInitializing.
+@return  An error code indicating if the function call was successful.
+KErrNone on success, otherwise another of the system-wide error codes.
+*/	
+TInt CMdfHwDeviceAdapter::InitializeDecode()
+	{
+	ASSERT(iCodecOutputPort && iSinkInputPort);
+	
+	TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iCodecInputPort->MipBufferSize()));
+	if(err != KErrNone)
+		{
+		return err;
+		}
+		
+	iCodecInputPort->MipUseBuffer(*iInputBuffer);	
+	TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iCodecOutputPort->MopBufferSize()));
+	if(err != KErrNone)
+		{
+		return err;
+		}	
+
+	// Try to set up a tunnelbetween the output port of the PCM Pu 
+	// and the input port of the Sink Pu	
+	if (iPuLoader->TunnelSetup(*iCodecOutputPort, *iSinkInputPort) != KErrNone)
+		{
+		iSinkInputPort->MipUseBuffer(*iOutputBuffer);
+		}
+	iCodecOutputPort->MopUseBuffer(*iOutputBuffer);		
+	
+	// async calls, that callback to InitializeComplete()
+	iCodecPU->Initialize();
+	iAudioDevicePU->Initialize();
+	iState = EProcessingUnitInitializing;
+	iActiveWait->Start();
+	return KErrNone;
+	}
+
+/*
+Starts the decode operation, providing that the intial state of the
+CMdfHwDeviceAdapter is EProcessingUnitLoaded.
+@return  An error code indicating if the function call was successful.
+KErrNone on success, otherwise another of the system-wide error codes.
+*/
+TInt CMdfHwDeviceAdapter::StartDecode()
+	{	
+	TInt err = KErrNone;
+	if (iState == EProcessingUnitLoaded)
+		{
+		err = InitializeDecode();
+		}
+	if (err != KErrNone)
+		{
+		return err;
+		}
+	if (iState == EProcessingUnitIdle)
+		{
+		// Ensure that the LastBuffer flags are reset.
+		iInputBuffer->SetLastBuffer(EFalse);
+		iOutputBuffer->SetLastBuffer(EFalse);
+		}
+	return StartExecuting();	
+	}
+
+/*
+@see CMMFHwDevice::Stop()
+*/
+TInt CMdfHwDeviceAdapter::Stop()
+	{	
+	if(iState == EProcessingUnitExecuting || iState == EProcessingUnitPaused)
+		{			
+		iStopping = ETrue; // is used as a guard in ExecuteComplete
+		if(iAudioDevicePU)
+			{
+			iAudioDevicePU->Stop();	
+			}
+		if(iCodecPU)
+			{
+			iCodecPU->Stop();	
+			}
+				
+		iPCMPUCallbackComplete = EFalse;
+		iSourceSinkPUCallbackComplete = EFalse;
+				
+		iState = EProcessingUnitIdle;
+		iStopping = EFalse;	
+		}
+	return KErrNone;		
+	}
+
+/*
+@see CMMFHwDevice::Pause()
+*/
+TInt CMdfHwDeviceAdapter::Pause()
+	{
+	TInt err = KErrNone;
+	if(iState != EProcessingUnitPaused)
+		{
+		if(iAudioDevicePU)
+			{	
+			err = iAudioDevicePU->Pause();	
+			}
+		iState = EProcessingUnitPaused;
+		}	
+	return err;	
+	}
+
+/*
+@see CMMFHwDevice::Init()
+*/
+TInt CMdfHwDeviceAdapter::Init(THwDeviceInitParams& aDevInfo)
+	{	
+	if(!iCodecPU)
+		{
+		return KErrNotSupported;
+		}
+		
+	// Not currently using any other members of aDevInfo, except the Observer
+	// Set observer	
+	if(!aDevInfo.iHwDeviceObserver)
+		{
+		return KErrArgument;
+		}
+	iHwDeviceObserver = aDevInfo.iHwDeviceObserver;
+	
+	RPointerArray<MMdfInputPort> inputPorts;
+	// Get ports and set observers
+	TInt err = iCodecPU->GetInputPorts(inputPorts);		
+	if (err == KErrNone && inputPorts.Count() > 0)
+		{
+		iCodecInputPort = inputPorts[KZerothPort];
+		iCodecInputPort->MipSetObserver(*this);
+		}		
+	inputPorts.Close();	
+	if (err != KErrNone)
+		{
+		return err;
+		}		
+	if (!iCodecInputPort)
+		{
+		return KErrNotFound;
+		}
+
+	RPointerArray<MMdfOutputPort> outputPorts;
+	// Get ports and set observers
+	err = iCodecPU->GetOutputPorts(outputPorts);	
+	if (err == KErrNone && outputPorts.Count() > 0)
+		{
+		iCodecOutputPort = outputPorts[KZerothPort];
+		iCodecOutputPort->MopSetObserver(*this);
+		}		
+	outputPorts.Close();	
+	if (err != KErrNone)
+		{
+		return err;
+		}
+	if (!iCodecOutputPort)
+		{
+		return KErrNotFound;
+		}
+	
+	// Load SourceSink Pu	
+	TRAP(err, iAudioDevicePU = iPuLoader->LoadProcessingUnitL(*this, KUidSourceSinkPu));
+	if(err!=KErrNone)
+		{
+		return err;
+		}		
+
+	err = iAudioDevicePU->GetInputPorts(inputPorts);	
+	if (err == KErrNone && inputPorts.Count() > 0)
+		{
+		iSinkInputPort = inputPorts[KZerothPort];
+		iSinkInputPort->MipSetObserver(*this);
+		}		
+	inputPorts.Close();
+	if (err != KErrNone)
+		{
+		return err;
+		}
+	if (!iSinkInputPort)
+		{
+		return KErrNotFound;
+		}
+
+	
+	err = iAudioDevicePU->GetOutputPorts(outputPorts);	
+	if (err == KErrNone && outputPorts.Count() > 0)
+		{
+		iSourceOutputPort = outputPorts[KZerothPort];
+		iSourceOutputPort->MopSetObserver(*this);
+		}		
+	outputPorts.Close();
+	if (err != KErrNone)
+		{
+		return err;
+		}
+	if (!iCodecOutputPort)
+		{
+		return KErrNotFound;
+		}
+	
+	iState = EProcessingUnitLoaded;
+	return KErrNone;		
+	}
+
+/*
+@see CMMFHwDevice::CustomInterface()
+*/
+TAny* CMdfHwDeviceAdapter::CustomInterface(TUid aInterfaceId)
+	{
+	if (aInterfaceId == KUidHwDeviceSetupInterface)
+		{
+		MMdfHwDeviceSetup* hwDeviceSetup = this;
+		return hwDeviceSetup;
+		}
+	else if (aInterfaceId.iUid == KMmfPlaySettingsCustomInterface)
+		{
+		return iSinkInputPort->MipCustomInterface(aInterfaceId);
+		}
+	else if (aInterfaceId.iUid == KMmfRecordSettingsCustomInterface)
+		{
+		return iSourceOutputPort->MopCustomInterface(aInterfaceId);
+		}
+	else if (aInterfaceId == KUidCustomInterfaceDevSoundBitRate)
+		{
+		return iCodecPU->CustomInterface(aInterfaceId);
+		}
+	else		
+		{
+		return NULL;
+		}
+	}
+
+/*
+@see CMMFHwDevice::ThisHwBufferFilled()
+*/
+TInt CMdfHwDeviceAdapter::ThisHwBufferFilled(CMMFBuffer& aFillBufferPtr)
+	{
+	aFillBufferPtr.SetStatus(EFull);	
+	iCodecInputPort->MipWriteData(aFillBufferPtr);
+	return KErrNone;
+	}
+
+/*
+@see CMMFHwDevice::ThisHwBufferEmptied()
+*/
+TInt CMdfHwDeviceAdapter::ThisHwBufferEmptied(CMMFBuffer& /*aEmptyBufferPtr*/)
+	{
+	if (iOutputBuffer->LastBuffer())
+		{
+		CMMFDataBuffer* buffer = static_cast <CMMFDataBuffer*> (iOutputBuffer);
+		buffer->Data().SetLength(0);
+		iHwDeviceObserver->EmptyThisHwBuffer(*iOutputBuffer);
+		}
+	else	
+		{
+		iCodecOutputPort->MopReadData(*iOutputBuffer);
+		}
+	return KErrNone;
+	}
+
+/*
+@see CMMFHwDevice::SetConfig()
+*/
+TInt CMdfHwDeviceAdapter::SetConfig(TTaskConfig& aConfig)
+	{
+	TInt err = KErrNone;
+	// Call to Configure the Codec PU
+	TPuTaskConfig config(aConfig);
+	err = iCodecInputPort->MipConfigure(config);
+	if(err != KErrNone)
+		{
+		return err;
+		}
+	err = iCodecOutputPort->MopConfigure(config);
+	if(err != KErrNone)
+		{
+		return err;
+		}
+
+	// configure the audio device
+	err = iSinkInputPort->MipConfigure(config);
+	if(err != KErrNone)
+		{
+		return err;
+		}
+	err = iSourceOutputPort->MopConfigure(config);
+	if(err != KErrNone)
+		{
+		return err;
+		}
+
+	return KErrNone;
+	}
+
+/*
+@see CMMFHwDevice::StopAndDeleteCodec()
+*/
+TInt CMdfHwDeviceAdapter::StopAndDeleteCodec()
+	{	
+	TInt stopError = Stop();
+	TInt deleteError = DeleteCodec();
+
+	if (stopError != KErrNone)
+		{
+		return stopError;
+		}		
+	else
+		{
+		return deleteError;
+		}		
+	}
+
+/*
+Unloads all Processing Units, and deletes any locally owned buffers.
+State is set to EProcessingUnitLoaderLoaded.
+
+@see CMMFHwDevice::DeleteCodec()
+*/
+TInt CMdfHwDeviceAdapter::DeleteCodec()
+	{
+	Stop();	
+	if (iCodecPU)
+		{
+		iPuLoader->UnloadProcessingUnit(iCodecPU);		
+		}		
+	if (iAudioDevicePU)	
+		{
+		iPuLoader->UnloadProcessingUnit(iAudioDevicePU);		
+		}	
+	
+	// CMdfHwDeviceAdapter does not own the I/O ports, which 
+	// have been deleted at this point by UnloadProcessingUnit()
+	iCodecInputPort = NULL;
+	iCodecOutputPort = NULL;
+	iSinkInputPort = NULL;
+	iSourceOutputPort = NULL;	
+		
+	delete iInputBuffer;
+	iInputBuffer = NULL;
+	delete iOutputBuffer;
+	iOutputBuffer = NULL;
+	
+	iState = EProcessingUnitLoaderLoaded;
+	
+	return KErrNone;
+	}
+
+/*
+@see MMdfInputPortObserver::MipoWriteDataComplete()
+*/
+void CMdfHwDeviceAdapter::MipoWriteDataComplete(const MMdfInputPort* aInputPort,
+	CMMFBuffer* aBuffer, TInt aErrorCode)
+	{
+	if(aErrorCode != KErrNone)
+		{
+		StopHwDevice(aErrorCode);
+		}
+	else
+		{
+		switch(iFuncCmd)
+			{
+			case EDevEncode:
+				{				
+				if(aInputPort == iCodecInputPort)
+					{
+					if(aBuffer->LastBuffer())
+						{
+						iCodecPU->Stop();
+						}
+					else
+						{
+						// if not the last buffer, then pass buffer back to source to get more data				
+						iSourceOutputPort->MopReadData(*iInputBuffer);
+						}
+					}
+				}
+				break;
+			case EDevDecode:
+				{
+				if(aInputPort == iCodecInputPort)
+					{				
+					if (!aBuffer->LastBuffer())
+						{	
+						// JW 22-05-06
+						// if the PU is idle (having been Stopped) then
+						// FillThisHwBuffer will cause a kern-exec,
+						// as the DevSoundSession no longer has a buffer
+						if(iState == EProcessingUnitExecuting) 
+							{
+							TInt err = iHwDeviceObserver->FillThisHwBuffer(*aBuffer);
+							if(err != KErrNone)
+								{
+								StopHwDevice(err);
+								}						
+							}
+						}
+					}
+				else // aInputPort == iSinkInputPort
+					{
+					if (!aBuffer->LastBuffer())
+						{				
+						if(iSinkInputPort->MipIsTunnelled())
+							{
+							// This callback shouldn't occur since it should be tunnelled with the sink input port
+							StopHwDevice(KErrArgument);
+							}
+						else
+							{
+							iCodecOutputPort->MopReadData(*iOutputBuffer);
+							}
+						}
+					}
+				}
+				break;
+			case EDevNullFunc:
+				// nothing at the moment, so fall through
+			default:
+				StopHwDevice(KErrNotSupported);	
+			}
+		}
+	}
+
+/*
+@see MMdfInputPortObserver::MipoDisconnectTunnelComplete()
+*/	
+void CMdfHwDeviceAdapter::MipoDisconnectTunnelComplete(const MMdfInputPort* aInputPort, 
+	TInt aErrorCode)
+	{
+	// The Inputport of the PcmCodecPu will no longer receive data.	
+	if(aErrorCode == KErrNone)
+		{
+		if(aInputPort == iCodecInputPort)
+			{
+			iPCMPuMipoStopCompleted = ETrue;
+			}
+		else if(aInputPort == iSinkInputPort)
+			{
+			// This shouldn't be called!
+			iHwDeviceObserver->Error(KErrNotFound);		
+			}
+		}
+	else
+		{
+		iHwDeviceObserver->Error(aErrorCode);
+		}	
+	}
+
+/*
+@see MMdfInputPortObserver::MipoRestartTunnelComplete()
+*/
+void CMdfHwDeviceAdapter::MipoRestartTunnelComplete(const MMdfInputPort* /*aInputPort*/,
+	TInt /*aErrorCode*/)
+	{
+	
+	}
+	
+/*
+@see MMdfOutputPortObserver::MopoReadDataComplete()
+*/
+void CMdfHwDeviceAdapter::MopoReadDataComplete(const MMdfOutputPort* aOutputPort, 
+	CMMFBuffer* aBuffer, TInt aErrorCode)
+	{
+	if(aErrorCode != KErrNone)
+		{
+		StopHwDevice(aErrorCode);
+		}
+	else
+		{
+		switch(iFuncCmd)
+			{
+			case EDevEncode:
+				{
+				if(aOutputPort == iSourceOutputPort)
+					{
+					iCodecInputPort->MipWriteData(*aBuffer);
+					}
+				else // aPu == iCodecPU
+					{
+					TInt err = iHwDeviceObserver->EmptyThisHwBuffer(*aBuffer);
+					if(err !=KErrNone)
+						{
+						StopHwDevice(err);
+						}
+					}
+				}
+				break;
+			case EDevDecode:
+				{
+				if(aOutputPort == iCodecOutputPort)
+					{
+					if(iCodecOutputPort->MopIsTunnelled())
+						{
+						// This callback shouldn't occur since it should be tunnelled with the sink input port
+						StopHwDevice(KErrArgument);
+						}
+					else
+						{
+						iSinkInputPort->MipWriteData(*aBuffer);
+						}
+					}
+				}
+				break;
+			case EDevNullFunc:
+				// nothing at the moment, so fall through
+			default:
+				StopHwDevice(KErrNotSupported);
+			}		
+		}
+	}
+
+/*
+@see MMdfOutputPortObserver::MopoDisconnectTunnelComplete()
+*/	
+void CMdfHwDeviceAdapter::MopoDisconnectTunnelComplete(const MMdfOutputPort* aOutputPort,
+	TInt aErrorCode)
+	{
+	if(!aOutputPort)
+		{
+		iHwDeviceObserver->Error(KErrArgument);
+		return;
+		}		
+		
+	// The last buffer has been set, and called back to MopoReadDataComplete
+	if(aErrorCode != KErrNone)
+		{
+		iHwDeviceObserver->Error(aErrorCode);
+		return;
+		}	
+
+	if(aOutputPort == iCodecOutputPort)
+		{		
+		iPCMPuMopoStopCompleted = ETrue;	
+		}
+	else if(aOutputPort == iSourceOutputPort)
+		{
+		iSourceSinkPuMopoStopCompleted = ETrue;
+		}
+	else
+		{
+		iHwDeviceObserver->Error(KErrArgument);
+		return;
+		}
+			
+	if(iPCMPuMipoStopCompleted && iPCMPuMopoStopCompleted && iSourceSinkPuMopoStopCompleted)
+		{
+		iHwDeviceObserver->Error(KErrNone);
+		iState = EProcessingUnitIdle;
+		}		
+	}
+
+/*
+@see MMdfOutputPortObserver::MopoRestartTunnelComplete()
+*/	
+void CMdfHwDeviceAdapter::MopoRestartTunnelComplete(const MMdfOutputPort* /*aOutputPort*/,
+	TInt /*aErrorCode*/)
+	{
+	
+	}
+
+/*
+@see MMdfProcessingUnitObserver::InitializeComplete()
+*/
+void CMdfHwDeviceAdapter::InitializeComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
+	{
+	iInitError = aErrorCode;
+	if(aErrorCode != KErrNone)
+		{
+		// stop waiting on the active scheduler if we were doing so
+		if (iState == EProcessingUnitInitializing)
+			{
+			// change state back to processing unit loaded
+			iState = EProcessingUnitLoaded;
+			iActiveWait->AsyncStop();
+			}
+		return;
+		}
+			
+	if(aPu == iCodecPU)
+		{
+		iPCMPUCallbackComplete = ETrue;
+		}
+	else if(aPu == iAudioDevicePU)
+		{
+		iSourceSinkPUCallbackComplete = ETrue;
+		}	
+
+	if(iPCMPUCallbackComplete && iSourceSinkPUCallbackComplete)
+		{
+		// reset the flags
+		iPCMPUCallbackComplete = EFalse;
+		iSourceSinkPUCallbackComplete = EFalse;
+		
+		// Both PUs initialised OK
+		if (iState == EProcessingUnitInitializing)
+			{
+			iActiveWait->AsyncStop();
+			}
+		iState = EProcessingUnitIdle;
+		}
+	}
+
+/*
+@see MMdfProcessingUnitObserver::ExecuteComplete()
+*/
+void CMdfHwDeviceAdapter::ExecuteComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
+	{
+	if(iStopping)
+		{
+		return;
+		}
+		
+	if (iExecuteError == KErrNone)
+		{
+		iExecuteError = aErrorCode;
+		}
+	 		
+	if(aPu == iCodecPU)
+		{
+		iPCMPUCallbackComplete = ETrue;
+		}
+	else if(aPu == iAudioDevicePU)
+		{
+		iSourceSinkPUCallbackComplete = ETrue;
+		}	
+
+	if(iExecuteError != KErrNone || (iPCMPUCallbackComplete && iSourceSinkPUCallbackComplete))
+		{
+		if (iState == EProcessingUnitExecuting)
+			{
+			// stop the hardware device if we are still executing
+			StopHwDevice(iExecuteError);		
+			iState = EProcessingUnitIdle;
+			}
+		// reset the flags
+		iPCMPUCallbackComplete = EFalse;
+		iSourceSinkPUCallbackComplete = EFalse;					
+		}
+	}
+
+/*
+@see MMdfHwDeviceSetup::::SetDataTypesL()
+*/
+void CMdfHwDeviceAdapter::SetDataTypesL(TFourCC aSrcType, TFourCC aDestType)
+	{
+	// Find and load an appropriate Codec
+	iCodecPU = iPuLoader->LoadProcessingUnitL(*this, aSrcType, aDestType);
+	}
+
+/*
+Called to indicate that the Hardware Device has been stopped, leading
+to callbacks to the observer. 
+@see MMMFHwDeviceObserver::Stopped()
+@see MMMFHwDeviceObserver::Error()
+*/
+void CMdfHwDeviceAdapter::StopHwDevice(TInt error)
+	{
+	iHwDeviceObserver->Stopped();
+	iHwDeviceObserver->Error(error);		
+	}
+
+/*
+Returns the state of the Hardware Device Adapter object.
+*/
+void CMdfHwDeviceAdapter::GetState(THwDevAdapterState& aState) const
+	{
+	aState = iState;	
+	}
+