diff -r 735348f59235 -r 948c7f65f6d4 omxil/mmilapi/unittest/test_plugins/dummypcmrenderer/dummypcmrenderer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxil/mmilapi/unittest/test_plugins/dummypcmrenderer/dummypcmrenderer.cpp Wed Sep 01 12:38:50 2010 +0100 @@ -0,0 +1,532 @@ +// Copyright (c) 2008-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 "dummypcmrenderer.h" +#include "iltestuids.hrh" +#include "tilstructtypes.h" +#include +#include + + +#define KDummyPCM16FormatUid 0x10111126 //dummy + +const TInt KBufferSize = 16384; // we need 16k to hold a pcm packet + +const TInt KDefaultSampleRate = 8000; +const TInt KDefaultNumberChannels = 1; + +const TInt KInputPortIndex = 0; + + +// ------------------------------------------------------------------------------------------ +// CDummyPcmRenderer::CInputPort Implementation + +CDummyPcmRenderer::CInputPort::CInputPort(CDummyPcmRenderer& aParent) + : CActive(EPriorityNormal), + iParent(aParent), + iSampleRate(KDefaultSampleRate), + iChannels(KDefaultNumberChannels), + iBufferSize(KBufferSize) + { + CActiveScheduler::Add(this); + } + +CDummyPcmRenderer::CInputPort::~CInputPort() + { + Cancel(); + iBuffers.Close(); + } + +CDummyPcmRenderer::CInputPort* CDummyPcmRenderer::CInputPort::NewL(CDummyPcmRenderer& aParent) + { + CInputPort* self = new (ELeave) CInputPort(aParent); + return self; + } + +TInt CDummyPcmRenderer::CInputPort::FillThisBuffer(CMMFBuffer& /*aInputBuffer*/) + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::CInputPort::EmptyThisBuffer(const CMMFBuffer& aInputBuffer) + { + TInt err = iBuffers.Append(&aInputBuffer); + if (err == KErrNone) + { + TILComponentState state; + if (iParent.GetState(state) != KErrNone) + { + return EComponentInvalid; + } + if (state == EComponentExecuting && !IsActive()) + { + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + } + return err; + } + +TInt CDummyPcmRenderer::CInputPort::TunnelRequest(MILComponentPortIf* aPort) + { + TILComponentState state; + if (iParent.GetState(state) != KErrNone) + { + return EComponentInvalid; + } + if (( state != EComponentLoaded) && (!iStopped)) + { + return EComponentInvalid; + } + + if (iPortConnectedTo) + { + // the port is already connected, return an error + return EPortAlreadyTunnelled; + } + iPortConnectedTo = const_cast(aPort); + return KErrNone; + } + +TInt CDummyPcmRenderer::CInputPort::DisconnectTunnel(MILComponentPortIf* /*aPort*/) + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::CInputPort::PortIndex() const + { + return KInputPortIndex; + } + +TPortDirection CDummyPcmRenderer::CInputPort::PortDirection() const + { + return EDirInput; + } + + +CMMFBuffer* CDummyPcmRenderer::CInputPort::CreateBufferL(TInt /*aBufferSize*/) + { + User::Leave(KErrNotSupported); + return NULL; + } + +TInt CDummyPcmRenderer::CInputPort::UseBuffer(CMMFBuffer& /*aBuffer*/) + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::CInputPort::FreeBuffer(CMMFBuffer* /*aBuffer*/) + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::CInputPort::FlushPort() + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::CInputPort::EnablePort() + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::CInputPort::DisablePort() + { + return KErrNotSupported; + } + +MILComponentIf* CDummyPcmRenderer::CInputPort::PortComponent() const + { + return &iParent; + } + +void CDummyPcmRenderer::CInputPort::SetVolume(TUint aVolume) + { + iVolume = aVolume; + } + +TUint CDummyPcmRenderer::CInputPort::Volume() + { + return iVolume; + } + +TUint CDummyPcmRenderer::CInputPort::BytesPlayed() + { + return iBytesPlayed; + } + +void CDummyPcmRenderer::CInputPort::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration) + { + iRampDuration = aRampDuration; + } + +TTimeIntervalMicroSeconds& CDummyPcmRenderer::CInputPort::VolumeRamp() + { + return iRampDuration; + } + +TInt CDummyPcmRenderer::CInputPort::SampleRate() + { + return iSampleRate; + } + +TInt CDummyPcmRenderer::CInputPort::Channels() + { + return iChannels; + } + +TUint32 CDummyPcmRenderer::CInputPort::BufferSize() const + { + return iBufferSize; + } + +void CDummyPcmRenderer::CInputPort::Execute() + { + if (!IsActive() && iBuffers.Count()>0) + { + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + } + +void CDummyPcmRenderer::CInputPort::Pause() + { + if (iParent.SoundDevice().Handle()) + { + iParent.SoundDevice().PausePlayBuffer(); + } + } + +void CDummyPcmRenderer::CInputPort::Stop() + { + Cancel(); + } + +void CDummyPcmRenderer::CInputPort::RunL() + { + + if (iCurrentBuffer != NULL) + { + // If we've been signalled with a buffer, callback that we've completed the writing of the + // buffer + if (iParent.Observer()) + { + iParent.Observer()->BufferDelivered(this, iCurrentBuffer); + if (iCurrentBuffer->LastBuffer()) + { + TILEvent thisEvent; + thisEvent.iEvent = EEventBufferFlag; + thisEvent.iData1 = PortIndex(); + thisEvent.iData2 = static_cast(KErrUnderflow); + iParent.Observer()->MsgFromILComponent(&iParent, thisEvent); + iParent.SoundDevice().Close(); + } + } + iCurrentBuffer = NULL; + } + + // only process the next buffer if there is no error + // error callbacks were handled in the previous block + if (iStatus == KErrNone) + { + if (iBuffers.Count()>0) + { + iCurrentBuffer = iBuffers[0]; + iBuffers.Remove(0); + + if (CMMFBuffer::IsSupportedDataBuffer(iCurrentBuffer->Type())) + { + TDes8& aBufferDes = (static_cast(iCurrentBuffer))->Data(); + iStatus = KRequestPending; + iParent.SoundDevice().PlayData(iStatus, aBufferDes); + SetActive(); + } + } + } + else + { + // In the real implementation here should be sending an error event back to the client + } + } + +void CDummyPcmRenderer::CInputPort::DoCancel() + { + if (iParent.SoundDevice().Handle()) + { + iParent.SoundDevice().CancelPlayData(); + iParent.SoundDevice().FlushPlayBuffer(); + } + } + +// ------------------------------------------------------------------------------------------ +// CDummyPcmRenderer Implementation + +CDummyPcmRenderer::CDummyPcmRenderer() + { + } + +CDummyPcmRenderer::~CDummyPcmRenderer() + { + delete iInputPort; + iSoundDevice.Close(); + } + +CDummyPcmRenderer* CDummyPcmRenderer::NewL() + { + CDummyPcmRenderer* self = new (ELeave) CDummyPcmRenderer; + return self; + } + +void CDummyPcmRenderer::CreateComponentL(const TDesC8& /*aComponentName*/, MILIfObserver& aComponentIfObserver) + { + iObserver = &aComponentIfObserver; + iInputPort = CInputPort::NewL(*this); + iState = EComponentLoaded; + } + +void CDummyPcmRenderer::CreateComponentL(const TUid& /*aUid*/, MILIfObserver& /*aComponentIfObserver*/) + { + User::LeaveIfError(KErrNotSupported); + }; + +void CDummyPcmRenderer::ReleaseComponent() + { + delete this; + } + +TInt CDummyPcmRenderer::GetComponentInputPorts(RPointerArray& aComponentPorts) const + { + return aComponentPorts.Append(iInputPort); + } + +TInt CDummyPcmRenderer::GetComponentOutputPorts(RPointerArray& /*aComponentPorts*/) const + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::SetConfig(const TILStruct& aConfig, const MILComponentPortIf* /*aComponentPort*/) + { + if (aConfig.Uid() == TUid::Uid(KUidMMFTTaskConfig)) + { + const TTaskConfig* config = TILTaskConfig::GetStructure(aConfig); + ASSERT(config); + iInputPort->iSampleRate = config->iRate; + iInputPort->iChannels = (config->iStereoMode & ETaskMono)? 1 : 2; + iInputPort->iInterleaved = (config->iStereoMode & ETaskInterleaved)?ETrue : EFalse; + return KErrNone; + } + + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::GetConfig(TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/) const + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::Initialize() + { + ASSERT(iObserver); + + TILEvent thisEvent; + thisEvent.iEvent = EEventCmdComplete; + thisEvent.iData1 = ECommandStateSet; + thisEvent.iData2 = EComponentIdle; + iObserver->MsgFromILComponent(this, thisEvent); + + iState = EComponentIdle; + return KErrNone; + } + +TInt CDummyPcmRenderer::UnInitialize() + { + ASSERT(iObserver); + + TILEvent thisEvent; + thisEvent.iEvent = EEventCmdComplete; + thisEvent.iData1 = ECommandStateSet; + thisEvent.iData2 = EComponentLoaded; + iObserver->MsgFromILComponent(this, thisEvent); + + iState = EComponentLoaded; + return KErrNone; + } + +TInt CDummyPcmRenderer::Execute() + { + ASSERT(iObserver); + TInt err = KErrNone; + if(!iSoundDevice.Handle()) + { + err = iSoundDevice.Open(); + } + + RMdaDevSound::TCurrentSoundFormatBuf buf; + if (err == KErrNone) + { + if(iState == EComponentPaused) + { + iSoundDevice.ResumePlaying(); + } + else + { + // Set play format (for input port) + iSoundDevice.GetPlayFormat(buf); + buf().iRate = iInputPort->SampleRate(); + buf().iChannels = iInputPort->Channels(); + buf().iBufferSize = KBufferSize; + buf().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM; + err = iSoundDevice.SetPlayFormat(buf); + } + } + iState = EComponentExecuting; + + TILEvent thisEvent; + thisEvent.iEvent = EEventCmdComplete; + thisEvent.iData1 = ECommandStateSet; + thisEvent.iData2 = EComponentExecuting; + iObserver->MsgFromILComponent(this, thisEvent); + + return err; + } + +TInt CDummyPcmRenderer::Pause() + { + iState = EComponentPaused; + iInputPort->Pause(); + return KErrNone; + } + +TInt CDummyPcmRenderer::Stop() + { + if(iState == EComponentExecuting || iState == EComponentPaused) + { + // Cancel and flush the device driver + iInputPort->Stop(); + + TILEvent thisEvent; + thisEvent.iEvent = EEventCmdComplete; + thisEvent.iData1 = ECommandStateSet; + thisEvent.iData2 = EComponentIdle; + iObserver->MsgFromILComponent(this, thisEvent); + + iState = EComponentIdle; + + // Close the sound device + iSoundDevice.Close(); + + return KErrNone; + } + else + { + // invalid state + return EComponentInvalid; + } + } + +TInt CDummyPcmRenderer::GetState(TILComponentState& aState) const + { + aState = iState; + return KErrNone; + } + +TInt CDummyPcmRenderer::SendCommand(const TILCommand& /*aCommand*/) + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::FlushAllPorts() + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::ComponentRoleEnum(TPtr8& /*aComponentRole*/, TUint32 /*aIndex*/) const + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::GetComponentVersion(TILComponentVersion& /*aVersion*/) const + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::SetComponentIfRole(const TDesC8& /*aComponentRole*/) + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::GetComponentIfRole(TDes8& /*aComponentRole*/) const + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::SetComponentIfRole(const TUid& /*aFormat*/) + { + // This interface is specific writen to support only this PCM renderer role + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::GetComponentIfRole(TUid& aFormat) const + { + aFormat = TUid::Uid(KDummyPCM16FormatUid); + return KErrNone; + } + +TAny* CDummyPcmRenderer::CustomInterface(TUid aUid) + { + if (aUid.iUid == KMmfPlaySettingsCustomInterface) + { + return static_cast(iInputPort); + } + return NULL; + } + +TInt CDummyPcmRenderer::SetExtConfig(const TDesC8& /*aParameterName*/, const TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/) + { + return KErrNotSupported; + } + +TInt CDummyPcmRenderer::GetExtConfig(const TDesC8& /*aParameterName*/, TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/) const + { + return KErrNotSupported; + } + + +MILIfObserver* CDummyPcmRenderer::Observer() const + { + return iObserver; + } + +RMdaDevSound& CDummyPcmRenderer::SoundDevice() + { + return iSoundDevice; + } + + +// ------------------------------------------------------------------------------------------ +// ECOM Implementation table entry + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(KUidDummyPcmRendererMILIFPlugin, CDummyPcmRenderer::NewL), + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + return ImplementationTable; + }