--- /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 <mmcccodecinformation.h>
+#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<KMceMaxSdpNameLength> aSdpName )
+ {
+ CMceComAudioCodec* self = NewLC( aSdpName );
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMceComAudioCodec::NewLC
+// -----------------------------------------------------------------------------
+//
+CMceComAudioCodec* CMceComAudioCodec::NewLC( TBuf8<KMceMaxSdpNameLength> 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<KMceMaxSdpNameLength> 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<TBool>( aReadStream.ReadUint8L() );
+ iSamplingFreq = aReadStream.ReadUint16L();
+ iPTime = aReadStream.ReadUint16L();
+ iMaxPTime = aReadStream.ReadUint16L();
+
+ iRedPayloadType = aReadStream.ReadUint8L();
+ iRedCount = aReadStream.ReadUint16L();
+ iComfortNoiseEnabled = static_cast<TBool>( 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<CMceComAudioCodec&>( 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<CMceComRtpSource&> ( 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<CMceSrvStream>& 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
+