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