diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccsubcontroller/src/mcccodecconfigurator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccsubcontroller/src/mcccodecconfigurator.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,1148 @@ +/* +* 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: Codec configurator for Mcc subthreads +* +*/ + + + + +// INCLUDE FILES +#include +#include +#include +#include + +#include <3gplibrary/mp4lib.h> + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mcccodecconfigurator.h" +#include "mccinternalcodecs.h" +#include "mmcccodecinformation.h" +#include "mmccinterfacedef.h" +#include "mccinternaldef.h" +#include "formatstatemachine.h" + +#include "mccvideosource.h" +#include "mccvideosink.h" +#include "mccfilesink.h" + +#include "mccsubcontrollerlogs.h" +#include "dtmfpayloadformatwrite.h" +#include "dtmfpayloadformatread.h" + +// LOCAL CONSTANTS +// AMR-NB Codec possible bitrates +const TInt KAmrNbBitrate475 = 4750; +const TInt KAmrNbBitrate515 = 5150; +const TInt KAmrNbBitrate590 = 5900; +const TInt KAmrNbBitrate670 = 6700; +const TInt KAmrNbBitrate740 = 7400; +const TInt KAmrNbBitrate795 = 7950; +const TInt KAmrNbBitrate102 = 10200; +const TInt KAmrNbBitrate122 = 12200; + +// AMR-WB Codec possible bitrates +const TInt KAmrWbBitrate660 = 6600; +const TInt KAmrWbBitrate885 = 8850; +const TInt KAmrWbBitrate1265 = 12650; +const TInt KAmrWbBitrate1425 = 14250; +const TInt KAmrWbBitrate1585 = 15850; +const TInt KAmrWbBitrate1825 = 18250; +const TInt KAmrWbBitrate1985 = 19850; +const TInt KAmrWbBitrate2305 = 23050; +const TInt KAmrWbBitrate2385 = 23850; + +// iLBC Codec possible bitrates +const TInt KIlbcBitrate1520 = 15200; +const TInt KIlbcBitrate1333 = 13330; + +// G.711 Modes +const TInt KG711ModeaLaw = 3; +const TInt KG711ModeuLaw = 2; + +// MACROS +#define MCC_CODEC_CONF_SET_VAD_L( curr_vad, get_func, new_vad, set_func ) \ +__SUBCONTROLLER( "MccCodecConfigurator:: setting vad" ) \ +TBool curr_vad( EFalse ); \ +TInt get_vad_err = get_func; \ +__SUBCONTROLLER_INT1( "MccCodecConfigurator:: get vad err:", get_vad_err ) \ +__SUBCONTROLLER_INT1( "MccCodecConfigurator:: curr vad:", curr_vad ) \ +if ( !get_vad_err && curr_vad != new_vad ) \ + { \ + TRAP_IGNORE(User::LeaveIfError( set_func )); \ + __SUBCONTROLLER_INT1( "MccCodecConfigurator:: vad set to:", new_vad ) \ + } + +#if ( defined __WINSCW__ ) || ( defined __WINS__ ) || ( defined TEST_EUNIT ) +#define MCC_CODEC_CONF_DISABLE_CONFIGURATION +#endif + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::ConfigureCodecL +// Generic codec configuration for codecs +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::ConfigureCodecL( + MDataSource& aDatasource, + MDataSink& aDatasink, + const TMccCodecInfo& aCodec, + CMccRtpMediaClock& aClock, + CMccSymStreamBase::TCodecState aCodecState, + MDataSink* aAssociatedDatasink ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL" ) + + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, checking codec" ) + User::LeaveIfError( TMccCodecInfo::CheckCodecInfo( aCodec ) ); + + if( KUidMmfAudioInput == aDatasource.DataSourceType() ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KUidMmfAudioInput" ) + MMMFAudioInput& record_device = static_cast( aDatasource ); + CPayloadFormatWrite& format_enc = static_cast( aDatasink ); + DoConfigureLiveAudioUplinkStreamL( record_device, format_enc, aCodec, aClock, aCodecState ); + } + else if( KUidMmfAudioOutput == aDatasink.DataSinkType() ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KUidMmfAudioOutput" ) + MMMFAudioOutput& play_device = static_cast( aDatasink ); + CPayloadFormatRead& format_dec = static_cast( aDatasource ); + DoConfigureLiveAudioDownlinkStreamL( play_device, format_dec, aCodec, aCodecState ); + } + else if( KMccFileSourceUid == aDatasource.DataSourceType() ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KMccFileSourceUID" ) + if ( KMccFileSinkUid != aDatasink.DataSinkType() ) + { + CPayloadFormatWrite& format = static_cast( aDatasink ); + DoConfigureClipUplinkStreamL( format, aCodec, aAssociatedDatasink, aClock ); + PassPrerollFromSinkToSourceL(aAssociatedDatasink, &aDatasource); + } + } + else if ( KMccFileSinkUid == aDatasink.DataSinkType() ) + { + if ( KMccVideoSourceUid == aDatasource.DataSourceType() ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KMccFileSinkUID, KMccVideoSourceUid" ) + DoConfigureCameraL( static_cast( aDatasource ), aCodec ); + DoConfigureFileSinkL( static_cast( aDatasink ), aCodec ); + } + else + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KMccFileSinkUID, source decoder" ) + CPayloadFormatRead& formatDec = static_cast( aDatasource ); + TMccCodecInfoBuffer buffer( aCodec ); + formatDec.ConfigurePayloadFormatL( buffer ); + } + } + else if( KMccVideoSourceUid == aDatasource.DataSourceType() ) + { + CPayloadFormatWrite& format = static_cast( aDatasink ); + __SUBCONTROLLER( "CMccCodecConfigurator::ConfigureCodecL, KMccVideoSourceUID, video" ) + CMccVideoSource& recordDevice = static_cast( aDatasource ); + DoConfigureLiveVideoUplinkStreamL( recordDevice, format, aCodec, aAssociatedDatasink, aClock ); + } + else if( KMccVideoSinkUid == aDatasink.DataSinkType() ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KMccVideoSinkUID" ) + if ( KUidMmfFormatDecode == aDatasource.DataSourceType() ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, source decoder" ) + CPayloadFormatRead& formatDec = static_cast( aDatasource ); + DoConfigureLiveVideoDownlinkStreamL( &aDatasink, formatDec, aCodec ); + } + } + else if ( aCodec.iFourCC == KMccFourCCIdDTMF ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KMccFourCCIdDTMF" ) + + if ( KUidMmfFormatDecode == aDatasource.DataSourceType() ) + { + CPayloadFormatRead& formatDec = static_cast( aDatasource ); + DoConfigureDtmfFormatL( formatDec, aCodec ); + } + else if ( KUidMmfFormatEncode == aDatasink.DataSinkType() ) + { + CPayloadFormatWrite& formatEnc = static_cast( aDatasink ); + DoConfigureDtmfFormatL( formatEnc, aCodec, aClock ); + } + else + { + User::Leave( KErrArgument ); + } + } + else + { + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, KErrArgument" ) + User::Leave( KErrArgument ); + } + __SUBCONTROLLER( "MccCodecConfigurator::ConfigureCodecL, exit" ) + } + + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureAmrL +// Configures the AMR record device +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureAmrL( + MMMFAudioOutput& aPlaybackDev, + const TMccCodecInfo& aCodec ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureAmrL, decoder" ) + + TFourCC fourcc( aCodec.iFourCC ); + const TUint32 fourccVal = fourcc.FourCC(); + if ( ( fourccVal == KMccFourCCIdAMRNB && + !IsSupportedAmrNbBitrate( aCodec.iBitrate ) ) || + ( fourccVal == KMccFourCCIdAMRWB && + !IsSupportedAmrWbBitrate( aCodec.iBitrate ) ) ) + { + User::Leave( KErrNotSupported ); + } + + __SUBCONTROLLER( "MccCodecConfigurator, bitrate allowed" ) + + CErrorConcealmentIntfc* errorConcealIf = + CErrorConcealmentIntfc::NewL( aPlaybackDev.SoundDevice() ); + + errorConcealIf->SetFrameMode( ETrue ); + + delete errorConcealIf; + errorConcealIf = NULL; + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureAmrL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureAmrL +// Configures the AMR playback device +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureAmrL( + MMMFAudioInput& aRecordDev, + const TMccCodecInfo& aCodec ) + { + + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureAmrL, encoder" ) + + TFourCC fourcc( aCodec.iFourCC ); + const TUint32 fourccVal = fourcc.FourCC(); + if ( ( fourccVal == KMccFourCCIdAMRNB && + !IsSupportedAmrNbBitrate( aCodec.iBitrate ) ) || + ( fourccVal == KMccFourCCIdAMRWB && + !IsSupportedAmrWbBitrate( aCodec.iBitrate ) ) ) + { + User::Leave( KErrNotSupported ); + } + + __SUBCONTROLLER( "MccCodecConfigurator, bitrate allowed" ) + + CSpeechEncoderConfig* speechEncConfIf = + CSpeechEncoderConfig::NewL( aRecordDev.SoundDevice() ); + CleanupStack::PushL( speechEncConfIf ); + + __SUBCONTROLLER( "MccCodecConfigurator, setting VAD" ) + + TBool requestedEnableVad = aCodec.iEnableDTX; + + MCC_CODEC_CONF_SET_VAD_L( currentVad, + speechEncConfIf->GetVadMode( currentVad ), + requestedEnableVad, + speechEncConfIf->SetVadMode( requestedEnableVad ) ) + + __SUBCONTROLLER_INT1( "MccCodecConfigurator, setting bitrate", aCodec.iBitrate ) + TUint bitrate( 0 ); + User::LeaveIfError( speechEncConfIf->GetBitrate( bitrate ) ); + if ( bitrate != aCodec.iBitrate ) + { + User::LeaveIfError( speechEncConfIf->SetBitrate( aCodec.iBitrate ) ); + } + + CleanupStack::PopAndDestroy( speechEncConfIf ); + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureAmrL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureG711L +// Configures the G.711 playback device +// ----------------------------------------------------------------------------- +// +void MccCodecConfigurator::DoConfigureG711L( + MMMFAudioOutput& aPlaybackDev, + const TMccCodecInfo& aCodec, + CMccSymStreamBase::TCodecState aCodecState ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG711L, decoder" ) + + CG711DecoderIntfc* g711DecIf = + CG711DecoderIntfc::NewL( aPlaybackDev.SoundDevice() ); + CleanupStack::PushL( g711DecIf ); + + // Cannot change mode on fly, + // changing it only right after the codec has been loaded + if ( aCodecState == CMccSymStreamBase::EStateCodecLoaded ) + { + if( KG711ModeaLaw == aCodec.iCodecMode ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG711L, aLaw" ) + User::LeaveIfError( g711DecIf->SetDecoderMode( + CG711DecoderIntfc::EDecALaw ) ); + } + else if( KG711ModeuLaw == aCodec.iCodecMode ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG711L, uLaw" ) + User::LeaveIfError( g711DecIf->SetDecoderMode( + CG711DecoderIntfc::EDecULaw ) ); + } + else + { + User::Leave( KErrNotSupported ); + } + } + + TBool enableCng = ConvertBoolean( aCodec.iEnableDTX ); + + MCC_CODEC_CONF_SET_VAD_L( currentVad, + g711DecIf->GetCng( currentVad ), + enableCng, + g711DecIf->SetCng( enableCng ) ) + + CleanupStack::PopAndDestroy( g711DecIf ); + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureG711L +// Configures the G.711 record device +// ----------------------------------------------------------------------------- +// +void MccCodecConfigurator::DoConfigureG711L( + MMMFAudioInput& aRecordDev, + const TMccCodecInfo& aCodec, + CMccSymStreamBase::TCodecState aCodecState ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG711L, encoder" ) + + CG711EncoderIntfc* g711EncIf = + CG711EncoderIntfc::NewL( aRecordDev.SoundDevice() ); + CleanupStack::PushL( g711EncIf ); + + // Cannot change mode on fly, + // changing it only right after the codec has been loaded + if ( aCodecState == CMccSymStreamBase::EStateCodecLoaded ) + { + if( KG711ModeaLaw == aCodec.iCodecMode ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG711L, aLaw" ) + User::LeaveIfError( g711EncIf->SetEncoderMode( + CG711EncoderIntfc::EEncALaw ) ); + } + else if ( KG711ModeuLaw == aCodec.iCodecMode ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG711L, uLaw" ) + User::LeaveIfError( g711EncIf->SetEncoderMode( + CG711EncoderIntfc::EEncULaw ) ); + } + else + { + User::Leave( KErrNotSupported ); + } + } + + TBool enableVad = ConvertBoolean( aCodec.iEnableDTX ); + + MCC_CODEC_CONF_SET_VAD_L( currentVad, + g711EncIf->GetVadMode( currentVad ), + enableVad, + g711EncIf->SetVadMode( enableVad ) ) + + CleanupStack::PopAndDestroy( g711EncIf ); + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureG729L +// Configures the G.729 playback device +// ----------------------------------------------------------------------------- +// +void MccCodecConfigurator::DoConfigureG729( MMMFAudioOutput& /*aPlaybackDev*/ ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG729, decoder, NOP" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureG729L +// Configures the G.729 record device +// ----------------------------------------------------------------------------- +// +void MccCodecConfigurator::DoConfigureG729L( MMMFAudioInput& aRecordDev, + TBool aEnableCng ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureG729, encoder" ) + + CG729EncoderIntfc* encG729If = + CG729EncoderIntfc::NewL( aRecordDev.SoundDevice() ); + CleanupStack::PushL( encG729If ); + + TBool enableVad = ConvertBoolean( aEnableCng ); + + MCC_CODEC_CONF_SET_VAD_L( currentVad, + encG729If->GetVadMode( currentVad ), + enableVad, + encG729If->SetVadMode( enableVad ) ) + + CleanupStack::PopAndDestroy( encG729If ); + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureIlbcL +// Configures the iLBC playback device +// ----------------------------------------------------------------------------- +// +void MccCodecConfigurator::DoConfigureIlbcL( + MMMFAudioOutput& aPlaybackDev, + const TMccCodecInfo& aCodec, + CMccSymStreamBase::TCodecState aCodecState ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL decoder" ) + __SUBCONTROLLER_INT1( "MccCodecConfigurator::DoConfigureIlbcL aCodecState: ", + aCodecState ) + + // Cannot change mode nor CNG state on fly, changing it only right after + // the codec has been loaded. Same thing applies also to other parameters. + if ( CMccSymStreamBase::EStateCodecLoaded == aCodecState ) + { + CIlbcDecoderIntfc* decIlbcIf = + CIlbcDecoderIntfc::NewL( aPlaybackDev.SoundDevice() ); + CleanupStack::PushL( decIlbcIf ); + + if( KIlbcBitrate1520 == aCodec.iBitrate ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL, 20ms" ) + + User::LeaveIfError( decIlbcIf->SetDecoderMode( + CIlbcDecoderIntfc::E20msFrame ) ); + } + else if( KIlbcBitrate1333 == aCodec.iBitrate ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL, 30ms" ) + + User::LeaveIfError( decIlbcIf->SetDecoderMode( + CIlbcDecoderIntfc::E30msFrame ) ); + } + else + { + User::Leave( KErrNotSupported ); + } + + + TBool cngEnabled = ConvertBoolean( aCodec.iEnableDTX ); + + MCC_CODEC_CONF_SET_VAD_L( currentVad, + decIlbcIf->GetCng( currentVad ), + cngEnabled, + decIlbcIf->SetCng( cngEnabled ) ) + + CleanupStack::PopAndDestroy( decIlbcIf ); + } + + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL decoder, Exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureIlbcL +// Configures the iLBC record device +// ----------------------------------------------------------------------------- +// +void MccCodecConfigurator::DoConfigureIlbcL( + MMMFAudioInput& aRecordDev, + const TMccCodecInfo& aCodec, + CMccSymStreamBase::TCodecState aCodecState ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL encoder" ) + __SUBCONTROLLER_INT1( "MccCodecConfigurator::DoConfigureIlbcL aCodecState: ", + aCodecState ) + + // Cannot change mode nor VAD state on fly, changing it only right after + // the codec has been loaded. Same thing applies also to other parameters. + if ( CMccSymStreamBase::EStateCodecLoaded == aCodecState ) + { + CIlbcEncoderIntfc* encIlbcIf = + CIlbcEncoderIntfc::NewL( aRecordDev.SoundDevice() ); + CleanupStack::PushL( encIlbcIf ); + + if( KIlbcBitrate1520 == aCodec.iBitrate ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL, 20ms" ) + + User::LeaveIfError( encIlbcIf->SetEncoderMode( + CIlbcEncoderIntfc::E20msFrame ) ); + } + else if ( KIlbcBitrate1333 == aCodec.iBitrate ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL, 30ms" ) + + User::LeaveIfError( encIlbcIf->SetEncoderMode( + CIlbcEncoderIntfc::E30msFrame ) ); + } + else + { + User::Leave( KErrNotSupported ); + } + + TBool vadEnabled = ConvertBoolean( aCodec.iEnableDTX ); + + MCC_CODEC_CONF_SET_VAD_L( currentVad, + encIlbcIf->GetVadMode( currentVad ), + vadEnabled, + encIlbcIf->SetVadMode( vadEnabled ) ) + + CleanupStack::PopAndDestroy( encIlbcIf ); + } + + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureIlbcL encoder, Exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureCameraL +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureCameraL( CMccVideoSource& aVideoSource, + const TMccCodecInfo& aCodec ) + { + if( aCodec.iType == KUidMediaTypeVideo ) + { + aVideoSource.SetVideoCodecL( aCodec ); + } + else + { + aVideoSource.SetAudioCodecL( aCodec ); + } + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureCameraL +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureFileSinkL( CMccFileSink& aFileSink, + const TMccCodecInfo& aCodec ) + { + if( aCodec.iType == KUidMediaTypeVideo ) + { + aFileSink.SetVideoCodecL( aCodec ); + } + else + { + aFileSink.SetAudioCodecL( aCodec ); + } + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoGetCameraConfigurationL +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoGetCameraConfigurationL( + const TMccCodecInfo& /*aCodec*/, + const TDesC8& /*aParam*/ ) + { + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoGetClipConfigurationL +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoGetClipConfigurationL( TDes8& aParam ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoGetClipConfigurationL" ) + + TMccFileSourceSetting& setting = + (*reinterpret_cast( &aParam ))(); + + MP4Handle mp4Handle; + MP4Err err = MP4_OK; + + TFileName fileName( setting.iFileName ); + + const TInt KMccZeroTerminatorLen = 1; + __ASSERT_ALWAYS( + fileName.Length() + KMccZeroTerminatorLen <= fileName.MaxLength(), + User::Leave( KErrOverflow ) ); + + err = MP4ParseOpen( &mp4Handle, (wchar_t *) fileName.PtrZ() ); + + if ( err == MP4_OUT_OF_MEMORY ) + { + User::Leave( KErrNoMemory ); + } + + __ASSERT_ALWAYS( err == MP4_OK, User::Leave( KErrNotFound ) ); + + // Read audio settings + // + mp4_u32 audioLength = 0; + mp4_u32 audioType; + mp4_u8 framesPerSample; + mp4_u32 audioTimeScale; + mp4_u32 audioAverageBitRate = 0; + + err = MP4_OK; + err = MP4ParseRequestAudioDescription( mp4Handle, + ( mp4_u32* ) &audioLength, ( mp4_u32* ) &audioType, + ( mp4_u8* ) &framesPerSample, ( mp4_u32* ) &audioTimeScale, + ( mp4_u32* ) &audioAverageBitRate ); + + if ( err == MP4_OK && audioType != MP4_TYPE_NONE ) + { + if ( audioType == MP4_TYPE_AMR_NB ) + { + __SUBCONTROLLER( + "MccCodecConfigurator::DoGetClipConfigurationL, file contains AMR" ) + setting.iAudioFourCC = TFourCC( KMccFourCCIdAMRNB ); + setting.iAudioBitRate = audioAverageBitRate; + } + else + { + __SUBCONTROLLER( + "MccCodecConfigurator::DoGetClipConfigurationL, file contains unsupported audio" ) + setting.iAudioFourCC = TFourCC( KMccFourCCUnsupported ); + } + } + else + { + __SUBCONTROLLER( "MccCodecConfigurator::DoGetClipConfigurationL, no audio" ) + setting.iAudioFourCC = TFourCC(); + } + + + // Read video settings + // + mp4_u32 videoLength = 0; + TReal frameRate; + mp4_u32 videoType; + mp4_u32 videoWidth; + mp4_u32 videoHeight; + mp4_u32 videoTimeScale; + mp4_u32 videoAverageBitRate; + mp4_u32 streamSize; + + err = MP4_OK; + err = MP4ParseRequestVideoDescription( mp4Handle, + ( mp4_u32* ) &videoLength, &frameRate, ( mp4_u32* ) &videoType, + ( mp4_u32* ) &videoWidth, ( mp4_u32* ) &videoHeight, + ( mp4_u32* ) &videoTimeScale ); + + if ( err == MP4_OK && videoType != MP4_TYPE_NONE ) + { + if ( videoType == MP4_TYPE_H263_PROFILE_0 || + videoType == MP4_TYPE_AVC_PROFILE_BASELINE ) + { + __SUBCONTROLLER( + "MccCodecConfigurator::DoGetClipConfigurationL, file contains supported video" ) + + err = MP4ParseRequestStreamDescription( mp4Handle, + ( mp4_u32* ) &streamSize, ( mp4_u32* ) &videoAverageBitRate ); + + __ASSERT_ALWAYS( err == MP4_OK, User::Leave( KErrGeneral ) ); + + if ( videoType == MP4_TYPE_H263_PROFILE_0 ) + { + __SUBCONTROLLER( "H263" ) + setting.iVideoFourCC = TFourCC( KMccFourCCIdH263 ); + } + else + { + __SUBCONTROLLER( "AVC" ) + setting.iVideoFourCC = TFourCC( KMccFourCCIdAVC ); + } + // Round to have zero decimals for clearness sake + User::LeaveIfError( Math::Round( setting.iVideoFrameRate, frameRate, 0 ) ); + setting.iVideoFrameSize.iWidth = videoWidth; + setting.iVideoFrameSize.iHeight = videoHeight; + + // Average bitrate is for the whole stream, + // subtract audio average to get video average + setting.iVideoBitRate = videoAverageBitRate - audioAverageBitRate; + } + else + { + __SUBCONTROLLER( + "MccCodecConfigurator::DoGetClipConfigurationL, file contains unsupported video" ) + setting.iVideoFourCC = TFourCC( KMccFourCCUnsupported ); + } + } + + else + { + __SUBCONTROLLER( + "MccCodecConfigurator::DoGetClipConfigurationL, no video" ) + setting.iVideoFourCC = TFourCC(); + } + + MP4ParseClose( mp4Handle ); + + // Audio and video might have different duration, take longer one + // + const TUint KMccMilliSecsToMicroSecs = 1000; + TUint32 duration = videoLength > audioLength ? videoLength : audioLength; + duration = duration * KMccMilliSecsToMicroSecs; + setting.iDuration = duration; + + setting.iPosition = 0; + + __SUBCONTROLLER_INT1( "duration:", setting.iDuration.Int64() ) + __SUBCONTROLLER_INT1( "position:", setting.iPosition.Int64() ) + __SUBCONTROLLER_INT1( "videoframerate:", (TInt) setting.iVideoFrameRate ) + __SUBCONTROLLER_INT1( "videobitrate:", setting.iVideoBitRate ) + __SUBCONTROLLER_INT2( "videoframesize width:", + setting.iVideoFrameSize.iWidth, + " height:", + setting.iVideoFrameSize.iHeight ) + __SUBCONTROLLER_INT1( "audiobitrate:", setting.iAudioBitRate ) + __SUBCONTROLLER_INT1( "audio fourcc:", setting.iAudioFourCC.FourCC() ) + __SUBCONTROLLER_INT1( "video fourcc:", setting.iVideoFourCC.FourCC() ) + + __SUBCONTROLLER( "MccCodecConfigurator::DoGetClipConfigurationL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureLiveAudioUplinkStreamL +// Uplink/Record codec configuration +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureLiveAudioUplinkStreamL( + MMMFAudioInput& aRecordDevice, + CPayloadFormatWrite& aFormatter, + const TMccCodecInfo& aCodec, + CMccRtpMediaClock& aClock, + CMccSymStreamBase::TCodecState aCodecState ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureLiveAudioUplinkStreamL" ) + + if ( aCodecState >= CMccSymStreamBase::EStateCodecLoaded ) + { + TFourCC fourcc( aCodec.iFourCC ); + + switch( fourcc.FourCC() ) + { + case KMccFourCCIdAMRNB: + case KMccFourCCIdAMRWB: + { + #ifdef MCC_CODEC_CONF_DISABLE_CONFIGURATION + + // Suppress compiler warnings + aRecordDevice = aRecordDevice; + + #else + + DoConfigureAmrL( aRecordDevice, aCodec ); + + #endif + } + break; + + case KMccFourCCIdG711: + { + #ifndef MCC_CODEC_CONF_DISABLE_CONFIGURATION + + DoConfigureG711L( aRecordDevice, aCodec, aCodecState ); + + #endif + } + break; + case KMccFourCCIdILBC: + { + #ifndef MCC_CODEC_CONF_DISABLE_CONFIGURATION + + DoConfigureIlbcL( aRecordDevice, aCodec, aCodecState ); + + #endif + } + break; + case KMccFourCCIdG729: + { + #ifndef MCC_CODEC_CONF_DISABLE_CONFIGURATION + + DoConfigureG729L( aRecordDevice, aCodec.iEnableDTX ); + + #endif + } + break; + default: + __SUBCONTROLLER_INT1( "MccCodecConfigurator, KErrNotSupported", fourcc.FourCC() ) + + User::Leave( KErrNotSupported ); + break; + } + } + + const TMccCodecInfoBuffer buffer( aCodec ); + aFormatter.ConfigurePayloadFormatL( buffer, aClock ); + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureLiveAudioUplinkStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureLiveAudioDownlinkStreamL +// Downlink/Playback codec configuration +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureLiveAudioDownlinkStreamL( + MMMFAudioOutput& aPlayDevice, + CPayloadFormatRead& aFormatter, + const TMccCodecInfo& aCodec, + CMccSymStreamBase::TCodecState aCodecState ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureLiveAudioDownlinkStreamL" ) + + if ( aCodecState >= CMccSymStreamBase::EStateCodecLoaded ) + { + TFourCC fourcc = aCodec.iFourCC; + + switch( fourcc.FourCC() ) + { + case KMccFourCCIdAMRNB: + case KMccFourCCIdAMRWB: + { + + #ifndef MCC_CODEC_CONF_DISABLE_CONFIGURATION + + DoConfigureAmrL( aPlayDevice, aCodec ); + + #endif + } + break; + + case KMccFourCCIdG711: + { + #ifndef MCC_CODEC_CONF_DISABLE_CONFIGURATION + + DoConfigureG711L( aPlayDevice, aCodec, aCodecState ); + + #endif + } + break; + case KMccFourCCIdILBC: + { + #ifndef MCC_CODEC_CONF_DISABLE_CONFIGURATION + + DoConfigureIlbcL( aPlayDevice, aCodec, aCodecState ); + + #endif + } + break; + case KMccFourCCIdG729: + { + // Nothing to do for G.729 decoder, but VoIP traces need that function + // to be called. This is call is safe for WINSCW also. + DoConfigureG729( aPlayDevice ); + } + break; + default: + User::Leave( KErrNotSupported ); + break; + } + } + + const TMccCodecInfoBuffer buffer( aCodec ); + aFormatter.ConfigurePayloadFormatL( buffer ); + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureLiveAudioDownlinkStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureDisplayL +// Uplink/Display codec configuration +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureDisplayL( + const TMccCodecInfo& aCodec, + MDataSink* aDatasink ) + { + if ( aDatasink && aDatasink->DataSinkType() == KMccVideoSinkUid ) + { + if ( aCodec.iType == KUidMediaTypeAudio ) + { + static_cast( aDatasink )->SetAudioCodecL( aCodec ); + } + else + { + static_cast( aDatasink )->SetVideoCodecL( aCodec ); + } + } + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::PassPrerollFromSinkToSourceL +// Passes preroll value from sink to source +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::PassPrerollFromSinkToSourceL( + MDataSink* aDataSink, MDataSource* aDataSource) + { + if ( aDataSource && + aDataSink && + aDataSource->DataSourceType().iUid == KImplUidMccFileSource && + aDataSink->DataSinkType().iUid == KImplUidMccVideoSink ) + { + // Pass preroll value from sink to source + CMccDataSink* mccVideoSink = static_cast( aDataSink ); + __ASSERT_DEBUG( mccVideoSink, + User::Panic( + _L("MccCodecConfigurator::PassPrerollFromSinkToSourceL mccVideoSink == 0"), + KErrArgument ) ); + __ASSERT_ALWAYS( mccVideoSink, User::Leave(KErrArgument) ); + CMccDataSource* mccFileSource = static_cast( aDataSource ); + __ASSERT_DEBUG( mccFileSource, + User::Panic( + _L("MccCodecConfigurator::PassPrerollFromSinkToSourceL mccFileSource == 0"), + KErrArgument ) ); + __ASSERT_ALWAYS( mccFileSource, User::Leave(KErrArgument) ); + + TPckgBuf packageBuffer; + mccVideoSink->GetParameterL(KMccPrerollTime, packageBuffer ); + mccFileSource->SetParameterL(KMccPrerollTime, packageBuffer ); + } + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureClipUplinkStreamL +// Uplink/display codec configuration +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureClipUplinkStreamL( + CPayloadFormatWrite& aFormatter, + const TMccCodecInfo& aCodec, + MDataSink* aAssociatedSink, + CMccRtpMediaClock& aClock ) + { + TMccCodecInfoBuffer buffer( aCodec ); + aFormatter.ConfigurePayloadFormatL( buffer, aClock ); + DoConfigureDisplayL( aCodec, aAssociatedSink ); + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureLiveVideoUplinkStreamL +// Uplink/Record codec configuration +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureLiveVideoUplinkStreamL( + CMccVideoSource& aDataSource, + CPayloadFormatWrite& aFormatter, + const TMccCodecInfo& aCodec, + MDataSink* aAssociatedSink, + CMccRtpMediaClock& aClock ) + { + DoConfigureCameraL( aDataSource, aCodec ); + TMccCodecInfoBuffer buffer( aCodec ); + aFormatter.ConfigurePayloadFormatL( buffer, aClock ); + DoConfigureDisplayL( aCodec, aAssociatedSink ); + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureDtmfFormatL +// Configures DTMF mediaformat plugin. +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureDtmfFormatL( + CPayloadFormatRead& aFormatDecoder, + const TMccCodecInfo& aCodec ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureDtmfFormatL, downlink" ) + + CDTMFPayloadFormatRead& formatRead + = reinterpret_cast( aFormatDecoder ); + + const TMccCodecInfoBuffer buffer( aCodec ); + formatRead.ConfigurePayloadFormatL( buffer ); + formatRead.SetPayloadFormat( EDTMFPayloadFormatEvent ); + + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureDtmfFormatL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureDtmfFormatL +// Configures DTMF mediaformat plugin. +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureDtmfFormatL( + CPayloadFormatWrite& aFormatEncoder, + const TMccCodecInfo& aCodec, + CMccRtpMediaClock& aClock ) + { + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureDtmfFormatL, uplink" ) + + CDTMFPayloadFormatWrite& formatWrite + = reinterpret_cast( aFormatEncoder ); + + const TMccCodecInfoBuffer buffer( aCodec ); + formatWrite.ConfigurePayloadFormatL( buffer, aClock ); + formatWrite.NotifyStopInDTMFString( ETrue ); + formatWrite.SetPayloadFormat( EDTMFPayloadFormatEvent ); + + __SUBCONTROLLER( "MccCodecConfigurator::DoConfigureDtmfFormatL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::DoConfigureLiveVideoDownlinkStreamL +// video Downlink codec configuration +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::DoConfigureLiveVideoDownlinkStreamL( + MDataSink* aDataSink, + CPayloadFormatRead& aFormatter, + const TMccCodecInfo& aCodec ) + { + TMccCodecInfoBuffer buffer( aCodec ); + aFormatter.ConfigurePayloadFormatL( buffer ); + DoConfigureDisplayL( aCodec, aDataSink ); + } + + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::GetCodecDefaultsL +// Uplink/Record codec configuration +// ----------------------------------------------------------------------------- +void MccCodecConfigurator::GetCodecDefaultsL( + const TUid aType, + TDes8& aParam, + TMccCodecInfo& aCodec ) + { + if( KMccVideoSourceUid == aType ) + { + DoGetCameraConfigurationL( aCodec, aParam ); + } + else if( KMccFileSourceUid == aType ) + { + DoGetClipConfigurationL( aParam ); + } + else + { + } + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::ChangeBitrateL +// Changes the current codec bitrate +// ----------------------------------------------------------------------------- +// +void MccCodecConfigurator::ChangeBitrateL( + const TMccCodecInfo& aCodec, + TUint aBitrate, + CMMFDevSound& aSounddevice ) + { + __SUBCONTROLLER( "MccCodecConfigurator::ChangeBitrateL" ) + + // Create an instance of speech encoder config custom interface + CSpeechEncoderConfig* speechEncConfIf = + CSpeechEncoderConfig::NewL( aSounddevice ); + + CleanupStack::PushL( speechEncConfIf ); + + // Only AMR supports bitrate change dynamically + TFourCC fourcc( aCodec.iFourCC ); + const TUint32 fourccVal = fourcc.FourCC(); + if ( KMccFourCCIdAMRNB == fourccVal && IsSupportedAmrNbBitrate( aBitrate ) ) + { + __SUBCONTROLLER_INT1( + "MccCodecConfigurator::ChangeBitrateL, setting amr nb bitrate:", + aBitrate ) + + User::LeaveIfError( speechEncConfIf->SetBitrate( aBitrate ) ); + } + else if ( KMccFourCCIdAMRWB == fourccVal && IsSupportedAmrWbBitrate( aBitrate ) ) + { + __SUBCONTROLLER_INT1( + "MccCodecConfigurator::ChangeBitrateL, setting amr wb bitrate:", + aBitrate ) + + User::LeaveIfError( speechEncConfIf->SetBitrate( aBitrate ) ); + } + else + { + __SUBCONTROLLER( "MccCodecConfigurator::ChangeBitrateL, bitrate not supported!" ) + User::Leave( KErrNotSupported ); + } + + CleanupStack::PopAndDestroy( speechEncConfIf ); + + __SUBCONTROLLER( "MccCodecConfigurator::ChangeBitrateL, exit" ) + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::ConvertBoolean +// Converts possibly dirty boolean parameter to EFalse/ETrue +// ----------------------------------------------------------------------------- +// +TBool MccCodecConfigurator::ConvertBoolean( TBool aParam ) + { + // As VoIP settings may contain negative values (-1 especially) for marking + // the setting as "Not set", we need to convert it into a real Symbian + // style ETrue/EFalse boolean. Especially in -1 param cases, we want to + // convert it into EFalse. + if( aParam > 0 ) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::IsSupportedAmrNbBitrate +// ----------------------------------------------------------------------------- +TBool MccCodecConfigurator::IsSupportedAmrNbBitrate( TInt aBitrate ) + { + return ( aBitrate == KAmrNbBitrate475 || + aBitrate == KAmrNbBitrate515 || + aBitrate == KAmrNbBitrate590 || + aBitrate == KAmrNbBitrate670 || + aBitrate == KAmrNbBitrate740 || + aBitrate == KAmrNbBitrate795 || + aBitrate == KAmrNbBitrate102 || + aBitrate == KAmrNbBitrate122 ); + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::IsSupportedAmrWbBitrate +// ----------------------------------------------------------------------------- +TBool MccCodecConfigurator::IsSupportedAmrWbBitrate( TInt aBitrate ) + { + return ( aBitrate == KAmrWbBitrate660 || + aBitrate == KAmrWbBitrate885 || + aBitrate == KAmrWbBitrate1265 || + aBitrate == KAmrWbBitrate1425 || + aBitrate == KAmrWbBitrate1585 || + aBitrate == KAmrWbBitrate1825 || + aBitrate == KAmrWbBitrate1985 || + aBitrate == KAmrWbBitrate2305 || + aBitrate == KAmrWbBitrate2385 ); + } + +// ----------------------------------------------------------------------------- +// MccCodecConfigurator::IlbcNeedsStopResume +// ----------------------------------------------------------------------------- +TBool MccCodecConfigurator::IlbcNeedsStopResume( TInt aOrigBitrate, + TInt aRequBitrate, const TFourCC& aCodec ) + { + const TFourCC tmp( KMccFourCCIdILBC ); + if ( tmp == aCodec && aOrigBitrate != aRequBitrate ) + { + __SUBCONTROLLER( "MccCodecConfigurator::IlbcNeedsStopResume ETrue" ) + + return ETrue; + } + else + { + __SUBCONTROLLER( "MccCodecConfigurator::IlbcNeedsStopResume EFalse" ) + + return EFalse; + } + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File