diff -r 000000000000 -r 1bce908db942 multimediacommsengine/mmceshared/src/mcecomaudiocodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommsengine/mmceshared/src/mcecomaudiocodec.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,579 @@ +/* +* Copyright (c) 2005 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 "mcecomaudiocodec.h" +#include "mceamrcodec.h" +#include "mceg711codec.h" +#include "mceg729codec.h" +#include "mceilbccodec.h" + +#include "mceserial.h" +#include "mceevents.h" + +#include "mcecomrtpsource.h" +#include "mcertpsource.h" + +#ifdef MCE_COMMON_SERVER_SIDE + +#include +#include "mcesrvstream.h" +#include "mcesrvsource.h" +#include "mcemmlogs.h" + +#endif//MCE_COMMON_SERVER_SIDE + +// CONSTANTS +const TUint KMceSamplingFreq8000 = 8000; + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::NewL +// ----------------------------------------------------------------------------- +// +CMceComAudioCodec* CMceComAudioCodec::NewL( TBuf8 aSdpName ) + { + CMceComAudioCodec* self = NewLC( aSdpName ); + CleanupStack::Pop( self ); + return self; + + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::NewLC +// ----------------------------------------------------------------------------- +// +CMceComAudioCodec* CMceComAudioCodec::NewLC( TBuf8 aSdpName ) + { + CMceComAudioCodec* self = new (ELeave) CMceComAudioCodec(); + CleanupStack::PushL( self ); + self->ConstructL( aSdpName ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::~CMceComAudioCodec +// ----------------------------------------------------------------------------- +// +CMceComAudioCodec::~CMceComAudioCodec() + { + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::CMceComAudioCodec +// ----------------------------------------------------------------------------- +// +CMceComAudioCodec::CMceComAudioCodec() + : CMceComCodec(), + iEnableVAD( EFalse ), + iSamplingFreq( 0 ), + iPTime( 0 ), + iMaxPTime( 0 ), + iRedPayloadType( KMcePayloadTypeUndefined ), + iRedCount( 0 ), + iComfortNoiseEnabled( EFalse ) + { + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::ConstructL +// ----------------------------------------------------------------------------- +// +CMceComAudioCodec* CMceComAudioCodec::CloneL() + { + CMceComAudioCodec* copy = new (ELeave) CMceComAudioCodec(); + CleanupStack::PushL( copy ); + copy->ConstructL( *this ); + CleanupStack::Pop( copy ); + return copy; + + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::ConstructL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::ConstructL( TBuf8 aSdpName ) + { + CMceComCodec::ConstructL( aSdpName ); + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::ConstructL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::ConstructL( CMceComAudioCodec& aCodec ) + { + CMceComCodec::ConstructL( aCodec ); + + iEnableVAD = aCodec.iEnableVAD; + iSamplingFreq = aCodec.iSamplingFreq; + iPTime = aCodec.iPTime; + iMaxPTime = aCodec.iMaxPTime; + + iRedPayloadType = aCodec.iRedPayloadType; + iRedCount = aCodec.iRedCount; + iComfortNoiseEnabled = aCodec.iComfortNoiseEnabled; + } + + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::InternalizeFlatL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::InternalizeFlatL( RReadStream& aReadStream ) + { + CMceComCodec::InternalizeFlatL( aReadStream ); + + iEnableVAD = static_cast( aReadStream.ReadUint8L() ); + iSamplingFreq = aReadStream.ReadUint16L(); + iPTime = aReadStream.ReadUint16L(); + iMaxPTime = aReadStream.ReadUint16L(); + + iRedPayloadType = aReadStream.ReadUint8L(); + iRedCount = aReadStream.ReadUint16L(); + iComfortNoiseEnabled = static_cast( aReadStream.ReadUint8L() ); + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::ExternalizeFlatL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::ExternalizeFlatL( RWriteStream& aWriteStream ) + { + CMceComCodec::ExternalizeFlatL( aWriteStream ); + + aWriteStream.WriteUint8L( iEnableVAD ); + aWriteStream.WriteUint16L( iSamplingFreq ); + aWriteStream.WriteUint16L( iPTime ); + aWriteStream.WriteUint16L( iMaxPTime ); + + aWriteStream.WriteUint8L( iRedPayloadType ); + aWriteStream.WriteUint16L( iRedCount ); + aWriteStream.WriteUint8L( iComfortNoiseEnabled ); + } + + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::UpdateL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::UpdateL( CMceComCodec& aUpdate ) + { + CMceComCodec::UpdateL( aUpdate ); + + CMceComAudioCodec& update = static_cast( aUpdate ); + + iEnableVAD = update.iEnableVAD; + iSamplingFreq = update.iSamplingFreq; + + if ( IS_RECEIVESTREAM( iStream ) ) + { + iPTime = update.iPTime; + iMaxPTime = update.iMaxPTime; + } + + iRedPayloadType = update.iRedPayloadType; + iRedCount = update.iRedCount; + iComfortNoiseEnabled = update.iComfortNoiseEnabled; + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::Factory +// ----------------------------------------------------------------------------- +// +TMceComAudioCodecFactory CMceComAudioCodec::Factory() + { + return TMceComAudioCodecFactory(); + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::CompareSdpIndex +// ----------------------------------------------------------------------------- +// +TInt CMceComAudioCodec::CompareSdpIndex( + const CMceComAudioCodec& aIndex1, const CMceComAudioCodec& aIndex2 ) + { + // NOTE: if zero (equals) is returned from here, order is strangely anyway + // changed. Returning positive value if indexes are equal is for avoiding + // this quirk. + + if ( aIndex1.iCodecSdpIndex >= aIndex2.iCodecSdpIndex ) + { + return (1); + } + else if ( aIndex1.iCodecSdpIndex < aIndex2.iCodecSdpIndex ) + { + return (-1); + } + else + { + return (0); + } + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::SetSamplingFreq +// ----------------------------------------------------------------------------- +// +TInt CMceComAudioCodec::SetSamplingFreq( TUint aSamplingFreq ) + { + if ( KMceSamplingFreq8000 == aSamplingFreq ) + { + iSamplingFreq = aSamplingFreq; + return KErrNone; + } + else + { + return KErrNotSupported; + } + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::SetPTime +// ----------------------------------------------------------------------------- +// +TInt CMceComAudioCodec::SetPTime( TUint aPTime ) + { + if ( ( 0 < aPTime ) && ( aPTime <= iMaxPTime ) ) + { + iPTime = aPTime; + return KErrNone; + } + else + { + return KErrNotSupported; + } + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::SetMaxPTime +// ----------------------------------------------------------------------------- +// +TInt CMceComAudioCodec::SetMaxPTime( TUint aMaxPTime ) + { + if ( ( 0 < aMaxPTime ) && ( iPTime <= aMaxPTime ) ) + { + iMaxPTime = aMaxPTime; + return KErrNone; + } + else + { + return KErrNotSupported; + } + } + +#ifdef MCE_COMMON_SERVER_SIDE + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::operator= +// ----------------------------------------------------------------------------- +// +/*lint -e1539 */ +CMceComCodec& CMceComAudioCodec::operator=( CMccCodecInformation& aMccCodec ) + { + + iPayloadType = aMccCodec.PayloadType(); + iBitrate = aMccCodec.Bitrate(); + iAllowedBitrates = aMccCodec.AllowedBitrates(); + iCodecMode = aMccCodec.CodecMode(); + iFourCC = aMccCodec.FourCC(); + iFrameSize = aMccCodec.FrameSize(); + + iEnableVAD = aMccCodec.VAD(); + iSamplingFreq = aMccCodec.SamplingFreq(); + iPTime = aMccCodec.PTime(); + iMaxPTime = aMccCodec.MaxPTime(); + + iRedPayloadType = aMccCodec.RedundancyPT(); + iRedCount = aMccCodec.RedCount(); + iComfortNoiseEnabled = + ( aMccCodec.ComfortNoiseGeneration() != KPayloadTypeUndefined ); + return *this; + + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoMccDecodeL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::DoMccDecodeL( CMccCodecInformation& aMccCodec ) + { + //copy values, which are not explicitely in SDP, from mcc codec + iSamplingFreq = aMccCodec.SamplingFreq(); + + iBitrate = aMccCodec.Bitrate(); + iRedPayloadType = aMccCodec.RedundancyPT(); + iRedCount = aMccCodec.RedCount(); + iComfortNoiseEnabled = aMccCodec.ComfortNoiseGeneration(); + //copy the value of VAD which are received from MO side + iEnableVAD = aMccCodec.VAD(); + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoMccEncodeL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::DoMccEncodeL( CMccCodecInformation& aMccCodec, + CMceSrvStream& aStream ) + { + User::LeaveIfError( aMccCodec.SetSamplingFreq( iSamplingFreq ) ); + + // Packet times are negotiated at session or media line level but all + // codecs in a group may not support all packet times. In this case + // codec's defaults are taken into use so that session negotiation is not + // unnecessary failed. + if ( KErrNone != aMccCodec.SetMaxPTime( iMaxPTime ) ) + { + iMaxPTime = aMccCodec.MaxPTime(); + } + + if ( KErrNone != aMccCodec.SetPTime( iPTime ) ) + { + iPTime = aMccCodec.PTime(); + } + + User::LeaveIfError( aMccCodec.EnableVAD( iEnableVAD ) ); + User::LeaveIfError( aMccCodec.SetBitrate( iBitrate ) ); + + if ( aStream.Source().Data().iType == KMceRTPSource ) + { + CMceComRtpSource& rtpSource = + static_cast ( aStream.Source().Data() ); + + User::LeaveIfError( + aMccCodec.SetJitterBufInactivityTimeOut( rtpSource.iInactivityTimer ) ); + User::LeaveIfError( + aMccCodec.SetJitterBufThreshold( rtpSource.iBufferTreshold ) ); + User::LeaveIfError( + aMccCodec.SetJitterBufBufferLength( rtpSource.iBufferLength ) ); + } + + DoMccEncodeComfortNoiseL( aMccCodec, aStream ); + DoMccEncodeRedundancyL( aMccCodec, aStream ); + } + + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoMccValidateL +// ----------------------------------------------------------------------------- +// +CMceComCodec* CMceComAudioCodec::DoMccValidateL( CMccCodecInformation& aMccCodec, + CMceSrvStream& aStream, + TMceNegotiationRole aRole ) + { + //if answerer mcc codec represents the received offer and codec the answer + //if offerer codec represents the sent offer and mcc codec the answer + TBool notValid = aRole == EMceRoleAnswerer ? + ( iAllowedBitrates && aMccCodec.AllowedBitrates() == 0 || + iAllowedBitrates > aMccCodec.AllowedBitrates() ) : + ( iAllowedBitrates && aMccCodec.AllowedBitrates() == 0 || + iAllowedBitrates < aMccCodec.AllowedBitrates() ); + + User::LeaveIfError( notValid ? KErrNotSupported : KErrNone ); + //Explicitly call default implementation of DoMccValidateL in base class + // to enable the check for codecMode + return CMceComCodec::DoMccValidateL( aMccCodec, aStream, aRole); + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoMccRequireSignalling +// ----------------------------------------------------------------------------- +// +TInt CMceComAudioCodec::DoMccRequireSignalling( + const CMceSrvStream& aStream, + const CMccCodecInformation& aMccCurentCodec, + const CMccCodecInformation& aMccUpdateCodec ) const + { + TInt action = KMceNoSignalling; + + if ( aStream.StreamType() == CMceComMediaStream::EReceiveStream || + aStream.StreamType() == CMceComMediaStream::EReceiveOnlyStream ) + { + if ( aMccCurentCodec.PTime() != aMccUpdateCodec.PTime() || + aMccCurentCodec.MaxPTime() != aMccUpdateCodec.MaxPTime() ) + { + action = KMceRequiresSignalling; + } + } + + return action; + + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoMccAdjustL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::DoMccAdjustL( CMccCodecInformation& aMccCodec, + CMceSrvStream& aStream ) + { + if( aStream.Data().iStreamType == CMceComMediaStream::ESendStream || + aStream.Data().iStreamType == CMceComMediaStream::ESendOnlyStream ) + { + // Do nothing if iPTime or iMaxPTime is greater than codecs supports. + // Then codecs default values is used. + aMccCodec.SetPTime( iPTime ); + aMccCodec.SetMaxPTime( iMaxPTime ); + User::LeaveIfError( aMccCodec.SetBitrate( iBitrate ) ); + + DoMccEncodeComfortNoiseL( aMccCodec, aStream ); + } + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoSetDefaultFmtpAttributeL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::DoSetDefaultFmtpAttributeL() + { + // NOP + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoDecodeAudioL +// ----------------------------------------------------------------------------- +// + +void CMceComAudioCodec::DoDecodeAudioL( + TInt aCodecIndex, + RPointerArray& aStreams, + CMceComAudioStream& aAudio, + CMceMediaManager& aManager ) + { + if ( aCodecIndex == 0 || IS_RECEIVESTREAM( &aAudio ) ) + { + SetEnabled( ETrue ); + } + + for( TInt sinkNdx = 0; sinkNdx < aAudio.Sinks().Count(); sinkNdx++ ) + { + CMceSrvStream* srvStream = + CMceSrvStream::NewL( aManager, + aAudio, + *aAudio.Source(), + *aAudio.Sinks()[ sinkNdx ], + *this ); + CleanupStack::PushL( srvStream ); + MCEMM_DEBUG_STREAM( "CMceComAudioCodec::DoDecodeAudioL(): decoded audio", + *srvStream ); + aStreams.AppendL( srvStream ); + CleanupStack::Pop( srvStream ); + } + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoMccEncodeComfortNoiseL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::DoMccEncodeComfortNoiseL( + CMccCodecInformation& aMccCodec, + CMceSrvStream& aStream ) + { + // If CN codec is not anymore present in session, disable comfort noise + // generation from this codec. + CMceComAudioCodec* searchCodec = Factory().CreateCodecLC( KMceSDPNameCn() ); + + CMceComCodec* cnCodec = aStream.Data().FindCodecL( *searchCodec ); + + iComfortNoiseEnabled = cnCodec ? cnCodec->iIsNegotiated : EFalse; + + // KPayloadTypeUndefined is used if cn is disabled + TUint8 comforNoisePt = + iComfortNoiseEnabled ? cnCodec->iPayloadType : KPayloadTypeUndefined; + + // If cn is disabled, handle removing the codec here + if ( !iComfortNoiseEnabled ) + { + aStream.Data().RemoveCodecL( cnCodec ); + if ( aStream.Data().BoundStream() ) + { + CMceComCodec* boundCnCodec = + aStream.Data().BoundStreamL().FindCodecL( *searchCodec ); + + aStream.Data().BoundStreamL().RemoveCodecL( boundCnCodec ); + } + } + + CleanupStack::PopAndDestroy( searchCodec ); + + // All codecs do not necessarily support cn, ignore errors + aMccCodec.SetComfortNoiseGeneration( comforNoisePt ); + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::DoMccEncodeRedundancyL +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::DoMccEncodeRedundancyL( + CMccCodecInformation& aMccCodec, + CMceSrvStream& aStream ) + { + // If red codec is not anymore present in session, disable redundancy + // from this codec. + CMceComAudioCodec* searchCodec = Factory().CreateCodecLC( KMceSDPNameRed() ); + + CMceComCodec* dtmfCodec = aStream.Data().FindCodecL( *searchCodec ); + if ( !dtmfCodec || !dtmfCodec->iIsNegotiated ) + { + iRedPayloadType = KMcePayloadTypeUndefined; + iRedCount = 0; + } + + CleanupStack::PopAndDestroy( searchCodec ); + + User::LeaveIfError( aMccCodec.SetRedundancyPT( iRedPayloadType ) ); + User::LeaveIfError( aMccCodec.SetRedCount( iRedCount ) ); + } + +// ----------------------------------------------------------------------------- +// CMceComAudioCodec::UpdateSendCodec +// ----------------------------------------------------------------------------- +// +void CMceComAudioCodec::UpdateSendCodec( + TInt& aCodecIndex, + CMceComAudioStream& aAudio, + CMceComAudioCodec& aCodec ) + { + if ( aCodecIndex == 0 && + IS_SENDSTREAM( &aAudio ) && + aCodec.SendSupported() && + aCodec.iIsNegotiated ) + { + // Changing send codec + aCodec.SetEnabled( ETrue ); + aCodecIndex = KErrNotFound; + } + } + +#endif// MCE_COMMON_SERVER_SIDE +