diff -r 000000000000 -r 71ca22bcf22a mmserv/voipaudioservices/VoIPIntfc/src/VoIPDownlinkStreamImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmserv/voipaudioservices/VoIPIntfc/src/VoIPDownlinkStreamImpl.cpp Tue Feb 02 01:08:46 2010 +0200 @@ -0,0 +1,627 @@ +/* + * Copyright (c) 2007-2008 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: VOIP Audio Services Downlink stream APIs. + * + */ + +#include +#include +#include +#include "debugtracemacros.h" +#include "VoIPAudioSession.h" +#include "VoIPAudioClientServer.h" +#include "VoIPFormatIntfcImpl.h" +#include "VoIPBaseCodecIntfcImpl.h" +#include "VoIPILBCDecoderIntfcImpl.h" +#include "VoIPG711DecoderIntfcImpl.h" +#include "VoIPG729DecoderIntfcImpl.h" +#include "VoIPJitterBufferIntfcImpl.h" +#include "VoIPSharedData.h" +#include "VoIPDownlinkStreamImpl.h" + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::NewL +// --------------------------------------------------------------------------- +// +CVoIPAudioDownlinkStreamImpl* +CVoIPAudioDownlinkStreamImpl::NewL(const TMMFPrioritySettings aPriority) + { + CVoIPAudioDownlinkStreamImpl* self = + new (ELeave) CVoIPAudioDownlinkStreamImpl(); + CleanupStack::PushL(self); + self->ConstructL(aPriority); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::~CVoIPAudioDownlinkStreamImpl +// --------------------------------------------------------------------------- +// +CVoIPAudioDownlinkStreamImpl::~CVoIPAudioDownlinkStreamImpl() + { + Close(); + + if (iMsgQHandler) + { + iMsgQHandler->Cancel(); + delete iMsgQHandler; + } + + if (iMsgQComHandler) + { + iMsgQComHandler->Cancel(); + delete iMsgQComHandler; + } + + if (iMsgQueue.Handle() > 0) + { + iMsgQueue.Close(); + } + + if (iMsgComQueue.Handle() > 0) + { + iMsgComQueue.Close(); + } + + if (iVoIPAudioSession.Handle() > 0) + { + iVoIPAudioSession.Close(); + } + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::CVoIPAudioDownlinkStreamImpl +// --------------------------------------------------------------------------- +// +CVoIPAudioDownlinkStreamImpl::CVoIPAudioDownlinkStreamImpl() : + iBufferPtr(0, 0, 0) + { + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::ConstructL +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::ConstructL( + const TMMFPrioritySettings aPriority) + { + // Pass ownership to the parent class + CVoIPAudioDownlinkStream::ConstructL(this); + iPriority = aPriority; + iG711FrameSize = KVoIPG711FrameLen20ms; + iFormat = EG711; + TInt err = iVoIPAudioSession.Connect(); + User::LeaveIfError(err); + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::Open +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::Open(MVoIPDownlinkObserver& aObserver) + { + iObserver = &aObserver; + + TInt err = CreateQueue(KDnLinkQueue, KVoIPMsgQSlots, EMsgBufQueue); + + if (err == KErrNone) + { + err = CreateQueue(KDnLinkComQueue, KVoIPMsgComQSlots, EMsgComQueue); + } + + if (err == KErrNone) + { + err = iVoIPAudioSession.OpenDownlink(iPriority); + } + + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::GetVersion +// Returns version of this component. +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::GetVersion(TVersion& aVersion) + { + aVersion = TVersion(1, 0, 0); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::GetMaxVolume +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::GetMaxVolume(TInt& aVolume) + { + aVolume = iVoIPAudioSession.GetMaxVolume(); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::SetVolume +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::SetVolume(TInt aVolume) + { + TInt err = iVoIPAudioSession.SetVolume(aVolume); + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::GetVolume +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::GetVolume(TInt& aVolume) + { + aVolume = iVoIPAudioSession.GetVolume(); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::GetSupportedFormatsL +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::GetSupportedFormatsL( + const TMMFPrioritySettings aPriority, + RArray& aFormats) + { + if (!iCodecFormats || aFormats.Count() <= 0) + { + RArray codecIDs; + CleanupClosePushL(codecIDs); + codecIDs.Reset(); + iVoIPAudioSession.GetSupportedDecoders(aPriority, codecIDs, + iG711FrameSize); + + TUint32 codec = 0; + TInt count = codecIDs.Count(); + TVoIPCodecFormat format; + aFormats.Reset(); + + for (TInt i = 0; i < count; i++) + { + codec = codecIDs[i]; + +#ifdef _DEBUG + TInt8 a = codec; + TInt8 b = codec >> 8; + TInt8 c = codec >> 16; + TInt8 d = codec >> 24; + RDebug::Print(_L("%c%c%c%c"), a, b, c, d); +#endif + format = ConvertFourCC(codec); + if (format != ENULL) + { + aFormats.Append(format); + } + } + + iCodecFormats = &aFormats; + CleanupStack::PopAndDestroy(&codecIDs); + } + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::SetFormatL +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::SetFormatL(TVoIPCodecFormat aFormat, + CVoIPFormatIntfc*& aIntfc) + { + // Check if requested codec is on the list of supported codecs + if (!IsCodecSupportedL(aFormat)) + { + iFormat = ENULL; + } + + // TODO: reuse when switching codecs on the fly and same codec is selected + delete aIntfc; + aIntfc = NULL; + + switch (iFormat) + { + case EG711: + case EG711_10MS: + { + aIntfc = CVoIPG711DecoderIntfcImpl::NewL(this); + iBufferLen = iG711FrameSize; + break; + } + case EG729: + { + aIntfc = CVoIPG729DecoderIntfcImpl::NewL(this); + iBufferLen = KVoIPG729FrameLen; + break; + } + case EILBC: + { + aIntfc = CVoIPILBCDecoderIntfcImpl::NewL(this); + iBufferLen = KVoIPILBCFrameLen; + break; + } + case EAMR_NB: + { + aIntfc = CVoIPBaseCodecIntfcImpl::NewL(this); + iBufferLen = KVoIPAMRNBFrameLen; + break; + } + case EPCM16: + { + aIntfc = CVoIPBaseCodecIntfcImpl::NewL(this); + iBufferLen = KVoIPPCM16FrameLen; + break; + } + default: + { + iFormat = ENULL; + iBufferLen = 0; + User::Leave(KErrNotSupported); + } + } + + TUint32 codecFourCC = CodecFourCC(iFormat); + iVoIPAudioSession.SetDecoder(codecFourCC); + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::GetFormat +// --------------------------------------------------------------------------- +// +TVoIPCodecFormat CVoIPAudioDownlinkStreamImpl::GetFormat() + { + return iFormat; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::SetAudioDevice +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::SetAudioDevice( + const TVoIPOutputDevice aDevice) + { + TInt err = iVoIPAudioSession.SetAudioDevice(aDevice); + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::GetAudioDevice +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::GetAudioDevice(TVoIPOutputDevice& aDevice) + { + TInt err = iVoIPAudioSession.GetAudioDevice(aDevice); + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::Start +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::Start() + { + TInt err = iVoIPAudioSession.StartDownlink(); + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::Stop +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::Stop() + { + TInt err = iVoIPAudioSession.StopDownlink(); + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::Close +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::Close() + { + iVoIPAudioSession.CloseDownlink(); + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::BufferFilled +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::BufferFilled(CVoIPDataBuffer* aBuffer) + { + TUint bufSeq = 0; + aBuffer->GetPayloadPtr(iBufferPtr); + CVoIPDataBuffer::TVoIPBufferType type; + aBuffer->GetBufferType(type); + + if (type == CVoIPDataBuffer::EJitterBuffer) + { + static_cast (aBuffer)->GetBufferSequence(bufSeq); + } + + TInt err = iVoIPAudioSession.BufferFilled(iBufferPtr, bufSeq); + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::CreateJitterBufferIntfcL +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::CreateJitterBufferIntfcL( + CVoIPJitterBufferIntfc*& aJBIntfc) + { + aJBIntfc = CVoIPJitterBufferIntfcImpl::NewL(&iVoIPAudioSession); + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::GetSession +// --------------------------------------------------------------------------- +// +RVoIPAudioSession* CVoIPAudioDownlinkStreamImpl::GetSession() + { + return &iVoIPAudioSession; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioStream::CreateQueue +// --------------------------------------------------------------------------- +// +TInt CVoIPAudioDownlinkStreamImpl::CreateQueue(const TDesC& aQueueName, + const TInt aNumSlots, const TQueueType aQueueType) + { + TInt err = KErrNone; + + if (aQueueType == EMsgBufQueue) + { + if (iMsgQueue.Handle() <= 0) + { + err = iMsgQueue.CreateGlobal(aQueueName, aNumSlots); + if (err != KErrNone) + { + return err; + } + } + + TRAP(err, ReceiveMsgQHandlerEventsL()); + } + else if (aQueueType == EMsgComQueue) + { + if (iMsgComQueue.Handle() <= 0) + { + err = iMsgComQueue.CreateGlobal(aQueueName, aNumSlots); + if (err != KErrNone) + { + return err; + } + } + + TRAP(err, ReceiveMsgQComHandlerEventsL()); + } + + return err; + } + +// --------------------------------------------------------------------------- +// CVoIPAudioStream::ReceiveMsgQHandlerEventsL +// Starts message queue handler (A/O) to monitor server side events +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::ReceiveMsgQHandlerEventsL() + { + if (iMsgQHandler) + { + iMsgQHandler->Cancel(); + } + else + { + iMsgQHandler = CQueueHandler::NewL(this, &iMsgQueue, iBufferLen); + } + + iMsgQHandler->Start(); + } + +// --------------------------------------------------------------------------- +// CVoIPAudioStream::ReceiveMsgQComHandlerEventsL +// Starts message queue handler (A/O) to monitor server side events +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::ReceiveMsgQComHandlerEventsL() + { + if (iMsgQComHandler) + { + iMsgQComHandler->Cancel(); + } + else + { + iMsgQComHandler = CQueueHandler::NewL(this, &iMsgComQueue); + } + + iMsgQComHandler->Start(); + } + +// --------------------------------------------------------------------------- +// CVoIPAudioStream::CodecFourCC +// --------------------------------------------------------------------------- +// +TUint32 CVoIPAudioDownlinkStreamImpl::CodecFourCC(TVoIPCodecFormat aFormat) + { + TUint32 codecFourCC; + + switch (aFormat) + { + case EG711_10MS: + case EG711: + { + codecFourCC = KMccFourCCIdG711; + break; + } + case EG729: + { + codecFourCC = KMccFourCCIdG729; + break; + } + case EILBC: + { + codecFourCC = KMccFourCCIdILBC; + break; + } + case EAMR_NB: + { + codecFourCC = KMccFourCCIdAMRNB; + break; + } + case EPCM16: + { + codecFourCC = KMMFFourCCCodePCM16; + break; + } + default: + { + codecFourCC = KFourCCNULL; + } + } + + return codecFourCC; + } + +// ----------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::ConvertFourCC +// ----------------------------------------------------------------------------- +// +TVoIPCodecFormat CVoIPAudioDownlinkStreamImpl::ConvertFourCC(TUint32 aCodec) + { + TVoIPCodecFormat format; + + switch (aCodec) + { + case KMccFourCCIdG711: + { + if (iG711FrameSize == KVoIPG711FrameLen10ms) + { + format = EG711_10MS; + TRACE_PRN_N(_L("VoIP->DNL: G711 10ms frame rate detected")); + } + else + { + format = EG711; + } + break; + } + case KMccFourCCIdG729: + format = EG729; + break; + case KMccFourCCIdILBC: + format = EILBC; + break; + case KMccFourCCIdAMRNB: + format = EAMR_NB; + break; + case KMMFFourCCCodePCM16: + format = EPCM16; + break; + default: + format = ENULL; + break; + } + + return format; + } + +// ----------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::IsCodecSupportedL +// ----------------------------------------------------------------------------- +// +TBool CVoIPAudioDownlinkStreamImpl::IsCodecSupportedL( + TVoIPCodecFormat aFormat) + { + TBool status = EFalse; + + if (!iCodecFormats) + { + // Client hasn't called GetSupportedFormatsL + RArray codecs; + CleanupClosePushL(codecs); + codecs.Reset(); + GetSupportedFormatsL(iPriority, codecs); //sets iCodecFormats + status = FindFormat(aFormat); + CleanupStack::PopAndDestroy(&codecs); + iCodecFormats = NULL; + } + else + { + status = FindFormat(aFormat); + } + + return status; + } + +// ----------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::FindFormat +// ----------------------------------------------------------------------------- +// +TBool CVoIPAudioDownlinkStreamImpl::FindFormat(TVoIPCodecFormat aFormat) + { + TBool found = EFalse; + + if (iCodecFormats) + { + if (iCodecFormats->Count() > 0) + { + if (iCodecFormats->Find(aFormat) == KErrNotFound) + { + // For backward compatibility with VAS 1.0 + if (aFormat == EG711) + { + if (iCodecFormats->Find(EG711_10MS) != KErrNotFound) + { + iFormat = EG711_10MS; + found = ETrue; + } + } + } + else + { + iFormat = aFormat; + found = ETrue; + } + } + } + + return found; + } + +// ======== CALLBACK FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::FillBuffer +// From MQueueHandlerObserver +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::FillBuffer(CVoIPDataBuffer* aBuffer) + { + iObserver->FillBuffer(*this, aBuffer); + } + +// --------------------------------------------------------------------------- +// CVoIPAudioDownlinkStreamImpl::Event +// From MQueueHandlerObserver +// --------------------------------------------------------------------------- +// +void CVoIPAudioDownlinkStreamImpl::Event(TInt aEventType, TInt aError) + { + iObserver->Event(*this, aEventType, aError); + } + +// End of file