/*
* Copyright (c) 2004-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: MCC iLBC CodecInformation
*
*/
// INCLUDE FILES
#include "mmcccodecilbc.h"
#include "mmccinterfacelogs.h"
#include "mccuids.hrh"
// LOCAL CONSTANTS AND MACROS
_LIT8( KIlbcMode20ms, "mode=20" );
_LIT8( KIlbcMode30ms, "mode=30" );
const TUint8 KiLBCKAPayloadSize20ms = 38;
const TUint8 KiLBCKeepAlivePayload20ms[KiLBCKAPayloadSize20ms] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
const TUint8 KiLBCKAPayloadSize30ms = 50;
const TUint8 KiLBCKeepAlivePayload30ms[KiLBCKAPayloadSize30ms] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
// Mask for 'allow all' bitrates. (defined in header)
const TUint KIlbcAllowAllBitrates = 0x00FF;
// ============================= LOCAL FUNCTIONS ===============================
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CMCCCodecILBC::CMCCCodecILBC
// default constructor
// -----------------------------------------------------------------------------
//
CMCCCodecILBC::CMCCCodecILBC() : CMccCodecInformation()
{
iBitrateMask = KIlbcAllowAllBitrates;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CMCCCodecILBC::ConstructL()
{
__INTERFACE( "CMCCCodecILBC::ConstructL()" )
SetSdpName( KILBCSdpName );
iKeepAliveData.Copy( KiLBCKeepAlivePayload30ms );
SetSamplingFreq( KIlbcSampleRate );
iHwFrameTime = KIlbcHwFrameTime; // default 30ms
SetBitrate( KIlbcBitrate30 ); // 30ms framesize used as default
EnableVAD( EFalse );
SetPayloadType( KDefaultIlbcPT );
SetMaxPTime( KIlbcMaxPTime );
SetPTime( KIlbcPTime );
iFourCC = KMccFourCCIdILBC;
iCodecMode = ENothing;
iPayloadFormatEncoder = KImplUidiLBCPayloadFormatEncode;
iPayloadFormatDecoder = KImplUidiLBCPayloadFormatDecode;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::NewL
// Static constructor.
// -----------------------------------------------------------------------------
//
CMCCCodecILBC* CMCCCodecILBC::NewL()
{
CMCCCodecILBC* self = new (ELeave) CMCCCodecILBC;
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::~CMCCCodecILBC
// Destructor
// -----------------------------------------------------------------------------
//
CMCCCodecILBC::~CMCCCodecILBC()
{
__INTERFACE( "CMCCCodecILBC::~CMCCCodecILBC()" )
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::EnableVAD
// Enable / Disable VAD
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::EnableVAD( TBool aEnableVAD )
{
iEnableVAD = aEnableVAD;
return KErrNone;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetBitrate
// Set Bitrate
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetBitrate( TUint aBitrate )
{
__INTERFACE_INT1( "CMCCCodecILBC::SetBitrate aBitrate", aBitrate )
__INTERFACE_INT1( "CMCCCodecILBC::SetBitrate iBitrate", iBitrate )
TBool isValid( ETrue );
switch ( aBitrate )
{
case KIlbcBitrate20:
iHwFrameTime = KIlbcPTime20; // 20ms frame
iKeepAliveData.Copy( KiLBCKeepAlivePayload20ms );
break;
case KIlbcBitrate30:
iHwFrameTime = KIlbcPTime30; // 30ms frame
iKeepAliveData.Copy( KiLBCKeepAlivePayload30ms );
break;
default:
isValid = EFalse;
break;
}
if ( isValid )
{
__INTERFACE( "CMCCCodecILBC::SetBitrate valid, adjusting" )
iBitrate = aBitrate;
AdjustCodec();
return KErrNone;
}
else
{
__INTERFACE( "CMCCCodecILBC::SetBitrate KErrNotSupported" )
return KErrNotSupported;
}
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetSamplingFreq
// Set Sampling Frequency
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetSamplingFreq( TUint32 aSamplingFreq )
{
if ( KIlbcSampleRate == aSamplingFreq )
{
iSamplingFreq = aSamplingFreq;
return KErrNone;
}
else
{
return KErrNotSupported;
}
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetSdpName
// Set SDP Name
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetSdpName( const TDesC8& aSdpName )
{
if ( !aSdpName.CompareF( KILBCSdpName ) )
{
iSdpName.Copy( aSdpName );
}
else
{
return KErrNotSupported;
}
return KErrNone;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetPayloadType
// Set PayloadType
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetPayloadType( TUint8 aPayloadType )
{
if ( aPayloadType > KMaxPayloadType || aPayloadType < KMinDynamicPT )
{
return KErrArgument;
}
else
{
iPayloadType = aPayloadType;
return KErrNone;
}
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetCodecMode
// Set Codec Mode
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetCodecMode( TCodecMode aCodecMode )
{
__INTERFACE_INT1( "CMCCCodecILBC::SetCodecMode aCodecMode", aCodecMode )
if ( ENothing == aCodecMode )
{
iCodecMode = aCodecMode;
return KErrNone;
}
else
{
return KErrNotSupported;
}
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::CreateFmtpAttrListL
// Builds fmtp line according to current parameters.
// -----------------------------------------------------------------------------
//
void CMCCCodecILBC::CreateFmtpAttrListL()
{
HBufC8* buf = HBufC8::NewLC( KMaxFmtpLen );
TPtr8 bufPtr = buf->Des();
// By default there is no need to construct the 30ms fmtp line. So
// let's do it only in 20ms mode.
if ( KIlbcBitrate20 == iBitrate )
{
bufPtr.Append( KIlbcMode20ms );
}
else
{
bufPtr.Append( KNullDesC8 );
}
// Update iFmtpAttr
SetFmtpAttrL( bufPtr, EFalse );
CleanupStack::PopAndDestroy( buf );
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::ParseFmtpAttrL
// Parse FMTP attribute
// -----------------------------------------------------------------------------
//
TBool CMCCCodecILBC::ParseFmtpAttrL( const TDesC8& aFmtp )
{
__INTERFACE( "CMCCCodecILBC::ParseFmtpAttrL, Entry" )
TPtrC8 curToken;
TLex8 fmtpLex( aFmtp );
TBool updated( EFalse );
curToken.Set( fmtpLex.NextToken() );
// Set bitrate according to mode indicated with fmtp attribute
if ( !curToken.Length() ||
KErrNotFound != curToken.Find( KIlbcMode30ms ) )
{
SetBitrate( KIlbcBitrate30 );
AdjustCodec();
updated = ETrue;
}
else if ( KErrNotFound != curToken.Find( KIlbcMode20ms ) )
{
SetBitrate( KIlbcBitrate20 );
AdjustCodec();
updated = ETrue;
}
else
{
__INTERFACE( "CMCCCodecILBC::ParseFmtpAttrL, KErrArgument" )
User::Leave( KErrArgument );
}
__INTERFACE_INT1( "CMCCCodecILBC::ParseFmtpAttrL, Exit updated", updated )
return updated;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::GetFmtpL
// Gets the fmtp attribute
// -----------------------------------------------------------------------------
//
TDesC8& CMCCCodecILBC::GetFmtpL()
{
__INTERFACE( "CMCCCodecILBC::GetFmtpL" )
if ( iFmtpAttr )
{
delete iFmtpAttr;
iFmtpAttr = NULL;
}
CreateFmtpAttrListL();
__INTERFACE( "CMCCCodecILBC::GetFmtpL, exit" )
return *iFmtpAttr;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetPTime
// Sets the packet time
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetPTime( TUint aPTime )
{
__INTERFACE_INT1( "CMCCCodecILBC::SetPTime, Entry aPTime", aPTime )
__INTERFACE_INT1( "CMCCCodecILBC::SetPTime, Entry iPTime", iPTime )
if ( iMaxPTime < aPTime )
{
__INTERFACE( "CMCCCodecILBC::SetPTime, KErrArgument 1" )
return KErrArgument;
}
else if( KMinPtime > aPTime )
{
__INTERFACE( "CMCCCodecILBC::SetPTime, KErrArgument 2" )
return KErrArgument;
}
else
{
if ( aPTime == KIlbcPTime20 || aPTime == KIlbcPTime30 )
{
iPTime = aPTime;
// Do not allow ptime vs. bitrate mismatch
AdjustCodec();
return KErrNone;
}
else if( ( KIlbcBitrate20 == iBitrate ) &&
( aPTime % KDefaultPtime == 0 ) )
{
iPTime = aPTime;
TInt mod = iMaxPTime % KDefaultPtime;
while( mod != 0 )
{
iMaxPTime = iMaxPTime - KMinPtime;
mod = iMaxPTime % KDefaultPtime;
}
if( iMaxPTime == 0 )
{
iMaxPTime = KMaxPtime;
}
return KErrNone;
}
else if( ( KIlbcBitrate30 == iBitrate ) &&
( aPTime % KIlbcPTime30 == 0 ) )
{
iPTime = aPTime;
TInt mod = iMaxPTime % KIlbcPTime30;
while( mod != 0 )
{
iMaxPTime = iMaxPTime - KMinPtime;
mod = iMaxPTime % KIlbcPTime30;
}
if( iMaxPTime == 0 )
{
iMaxPTime = KIlbcMaxPTime30;
}
return KErrNone;
}
else
{
__INTERFACE( "CMCCCodecILBC::SetPTime, KErrArgument 3" )
return KErrArgument;
}
}
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetMaxPTime
// Set Max PTime
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetMaxPTime( TUint aMaxPTime )
{
__INTERFACE_INT1( "CMCCCodecILBC::SetMaxPTime, Entry aMaxPTime", aMaxPTime )
__INTERFACE_INT1( "CMCCCodecILBC::SetMaxPTime, Entry iMaxPTime", iMaxPTime )
if ( aMaxPTime < iPTime )
{
__INTERFACE( "CMCCCodecILBC::SetMaxPTime, KErrArgument 1" )
return KErrArgument;
}
else
{
if ( aMaxPTime && ( KIlbcBitrate20 == iBitrate ) &&
( aMaxPTime % KDefaultPtime == 0 ) )
{
if ( KMaxPtime < aMaxPTime )
{
__INTERFACE( "CMCCCodecILBC::SetMaxPTime, KErrArgument 2" )
return KErrArgument;
}
else
{
iMaxPTime = aMaxPTime;
return KErrNone;
}
}
else if ( aMaxPTime && ( KIlbcBitrate30 == iBitrate ) &&
( aMaxPTime % KIlbcPTime30 == 0 ) )
{
if ( KIlbcMaxPTime30 < aMaxPTime )
{
__INTERFACE( "CMCCCodecILBC::SetMaxPTime, KErrArgument 3" )
return KErrArgument;
}
else
{
iMaxPTime = aMaxPTime;
return KErrNone;
}
}
else
{
__INTERFACE( "CMCCCodecILBC::SetMaxPTime, KErrArgument 4" )
return KErrArgument;
}
}
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::CloneDefaultsL
// Make a default setting clone from this iLBC codec
// -----------------------------------------------------------------------------
//
CMccCodecInformation* CMCCCodecILBC::CloneDefaultsL()
{
return CMCCCodecILBC::NewL();
};
// -----------------------------------------------------------------------------
// CMCCCodecILBC::CloneDetailedL
// Make a detailed clone from this iLBC codec
// -----------------------------------------------------------------------------
//
CMccCodecInformation* CMCCCodecILBC::CloneDetailedL()
{
CMCCCodecILBC* newCodec = CMCCCodecILBC::NewL();
CleanupStack::PushL( newCodec );
newCodec->SetBitrate( this->Bitrate() );
newCodec->SetCodecMode( this->CodecMode() );
newCodec->SetMaxPTime( this->MaxPTime() );
newCodec->SetPayloadType( this->PayloadType() );
newCodec->SetPTime( this->PTime() );
newCodec->SetSamplingFreq( this->SamplingFreq() );
newCodec->SetSdpName( this->SdpName() );
TDesC8& fmtp( this->GetFmtpL() );
if ( fmtp.Length() )
{
newCodec->ParseFmtpAttrL( this->GetFmtpL() );
}
CleanupStack::Pop( newCodec );
return newCodec;
};
// -----------------------------------------------------------------------------
// CMCCCodecILBC::RequireSignalling
// -----------------------------------------------------------------------------
//
TBool CMCCCodecILBC::RequireSignalling(
const CMccCodecInformation& aCandidate ) const
{
return CMccCodecInformation::RequireSignalling( aCandidate );
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetComfortNoiseGeneration
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetComfortNoiseGeneration( TUint8 aComfortNoisePT )
{
iComfortNoiseGenerationPt = aComfortNoisePT;
return KErrNone;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::SetAllowedBitrates
// -----------------------------------------------------------------------------
//
TInt CMCCCodecILBC::SetAllowedBitrates( TUint /*aBitrateMask*/ )
{
// iLBC does not really need the concept of 'allowed' bitrates because
// the bitrate setting handles assertion for bitrate correctness.
return KErrNone;
}
// -----------------------------------------------------------------------------
// CMCCCodecILBC::AdjustCodec
// -----------------------------------------------------------------------------
//
void CMCCCodecILBC::AdjustCodec()
{
__INTERFACE_INT1( "CMCCCodecILBC::AdjustCodec Entry iPTime",
iPTime )
__INTERFACE_INT1( "CMCCCodecILBC::AdjustCodec Entry iHwFrameTime",
iHwFrameTime )
// If default ptime is in use, it is adjusted based on mode of the codec
if ( iPTime == KIlbcPTime20 || iPTime == KIlbcPTime30 || !iPTime )
{
iPTime = ( KIlbcBitrate20 == iBitrate ) ? KIlbcPTime20 : KIlbcPTime30;
}
else if ( iPTime )
{
__INTERFACE( "CMCCCodecILBC::AdjustCodec ptime to closest possible" )
// Default ptime is not in use, we must adjust it to closest possible
// according to current iHwFrameTime (bitrate specific).
TInt ptmul = (TInt) iPTime / (TInt) iHwFrameTime;
iPTime = ptmul *
( ( KIlbcBitrate20 == iBitrate ) ? KIlbcPTime20 : KIlbcPTime30 );
}
__INTERFACE_INT1( "CMCCCodecILBC::AdjustCodec Exit iPTime",
iPTime )
}
// ========================== OTHER EXPORTED FUNCTIONS =========================
// End of File