diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccsubcontroller/src/mccsymsubthreadclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccsubcontroller/src/mccsymsubthreadclient.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,993 @@ +/* +* 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: Symmetric subthread client +* +*/ + + + +// INCLUDE FILES +#include +#include + +#include "mccsymsubthreadclient.h" +#include "mccsymulstream.h" +#include "mccsymdlstream.h" +#include "mccsymsimpledlstream.h" +#include "mccdtmfdlstream.h" +#include "mccdtmfulstream.h" +#include "mccrtpmanager.h" +#include "amrpayloadformatutil.h" +#include "mccinternalevents.h" +#include "mccsubcontrollerlogs.h" +#include "mmccsecureinterface.h" + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::CMccSymSubthreadClient +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +CMccSymSubthreadClient::CMccSymSubthreadClient( + MMccEventHandler* aObserver, + MMccResources* aMccResources, + TInt aLinkType, + TUint32 aMccSessionId ): + CMccSubThreadClientBase( aObserver, aMccResources, aLinkType, aMccSessionId ) + { + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::ConstructL() + { + __SUBCONTROLLER( "CMccSymSubthreadClient::ConstructL" ) + User::LeaveIfNull( iObserver ); + User::LeaveIfNull( iMccResources ); + iRtpmanager = CMccRtpManager::NewL( *this, *iMccResources, MccSessionId() ); + __SUBCONTROLLER( "CMccSymSubthreadClient::ConstructL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::NewL +// Static constructor. +// ----------------------------------------------------------------------------- +CMccSymSubthreadClient* CMccSymSubthreadClient::NewL( + MMccEventHandler* aObserver, + MMccResources* aMccResources, + TInt aLinkType, + TUint32 aMccSessionId ) + { + CMccSymSubthreadClient* self = + new ( ELeave ) CMccSymSubthreadClient( aObserver, aMccResources, aLinkType, aMccSessionId ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::~CMccSymSubthreadClient +// Destructor +// ----------------------------------------------------------------------------- +CMccSymSubthreadClient::~CMccSymSubthreadClient() + { + __SUBCONTROLLER( "CMccSymSubthreadClient::~CMccSymSubthreadClient" ) + + iStreams.ResetAndDestroy(); + iStreams.Close(); + + iUnusedStreams.Reset(); + iUnusedStreams.Close(); + + if( iRtpmanager ) + { + iRtpmanager->CloseSession(); + delete iRtpmanager; + } + __SUBCONTROLLER( "CMccSymSubthreadClient::~CMccSymSubthreadClient, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SetVolumeL +// Creates a new RTP session in a subthread +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::SetVolumeL( TInt aVolume ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SetVolumeL", aVolume ) + TInt strmCount = iStreams.Count(); + if( strmCount ) + { + for( TInt k = 0; k < strmCount; k++ ) + { + iStreams[k]->SetVolumeL( aVolume ); + } + } + else + { + __SUBCONTROLLER( "CMccSymSubthreadClient::SetVolumeL, no streams" ) + } + __SUBCONTROLLER( "CMccSymSubthreadClient::SetVolumeL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SetGainL +// Creates a new RTP session in a subthread +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::SetGainL( TInt aGain ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SetGainL", aGain ) + TInt strmCount = iStreams.Count(); + if( strmCount ) + { + for( TInt k = 0; k < strmCount; k++ ) + { + iStreams[k]->SetGainL( aGain ); + } + } + else + { + __SUBCONTROLLER( "CMccSymSubthreadClient::SetGainL, no streams" ) + } + __SUBCONTROLLER( "CMccSymSubthreadClient::SetGainL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::VolumeL +// Creates a new RTP session in a subthread +// ----------------------------------------------------------------------------- +TInt CMccSymSubthreadClient::GetVolumeL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetVolumeL for streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt volume = 0; + TInt index = FindStreamL( aStreamId ); + volume = iStreams[index]->VolumeL(); + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetVolumeL exit with", volume ) + return volume; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::GainL +// Creates a new RTP session in a subthread +// ----------------------------------------------------------------------------- +TInt CMccSymSubthreadClient::GetGainL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetGainL for streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt gain = 0; + TInt index = FindStreamL( aStreamId ); + gain = iStreams[index]->GainL(); + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetGainL exit with", gain ) + return gain; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::MaxVolumeL +// Creates a new RTP session in a subthread +// ----------------------------------------------------------------------------- +TInt CMccSymSubthreadClient::MaxVolumeL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::MaxVolumeL for streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt maxvolume = 0; + TInt index = FindStreamL( aStreamId ); + maxvolume = iStreams[index]->MaxVolumeL(); + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::MaxVolumeL exit with", maxvolume ) + return maxvolume; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::MaxGainL +// Creates a new RTP session in a subthread +// ----------------------------------------------------------------------------- +TInt CMccSymSubthreadClient::MaxGainL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::MaxGainL for streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt maxgain = 0; + TInt index = FindStreamL( aStreamId ); + maxgain = iStreams[index]->MaxGainL(); + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::MaxGainL exit with", maxgain ) + return maxgain; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SetBalanceL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::SetBalanceL( const TUint32 aStreamId, TInt aLeftBalance, + TInt aRightBalance ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SetBalanceL for streamId", aStreamId ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SetBalanceL for LeftBalance", aLeftBalance ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SetBalanceL for RightBalance", aRightBalance ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->SetBalanceL( aLeftBalance, aRightBalance ); + __SUBCONTROLLER( "CMccSymSubthreadClient::SetBalanceL exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::GetBalanceL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::GetBalanceL( const TUint32 aStreamId, TInt& aLeftBalance, + TInt& aRightBalance ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetBalanceL for streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->GetBalanceL( aLeftBalance, aRightBalance ); + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetBalanceL for LeftBalance", aLeftBalance ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetBalanceL for RightBalance", aRightBalance ) + __SUBCONTROLLER( "CMccSymSubthreadClient::GetBalanceL exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::OpenL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::OpenL( TInt aStreamType, + TFourCC aFourCC, + MDataSource* aDatasource, + MDataSink* aDatasink, + const TUint32 aStreamId, + TMMFPrioritySettings aSettings ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::OpenL for streamId", aStreamId ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient stream type", aStreamType ) + __ASSERT_ALWAYS( iSessionCreated, User::Leave( KErrNotReady ) ); + __ASSERT_ALWAYS( aDatasource, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( aDatasink, User::Leave( KErrArgument ) ); + + TUid sourceType = aDatasource->DataSourceType(); + TUid sinkType = aDatasink->DataSinkType(); + + iPrioritySettingsData = aSettings; + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient audio priority", iPrioritySettingsData.iPriority ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient audio preference", iPrioritySettingsData.iPref ) + + CMccSymStreamBase* stream( NULL ); + + TBool localAVToDisplayStream = ( aStreamType == KMccVideoLocalStream || + aStreamType == KMccAudioLocalStream ) && + sourceType == KMccFileSourceUid && + sinkType == KMccVideoSinkUid; + + if ( KMccDtmfStream == aStreamType && KMccRtpSourceUid == sourceType ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::OpenL, new CMccDtmfDlStream" ) + + stream = CMccDtmfDlStream::NewLC( aStreamId, this, iMccResources, + iRtpmanager, aFourCC, aStreamType, *iRtpMediaClock ); + } + else if ( KMccDtmfStream == aStreamType && KMccRtpSinkUid == sinkType ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::OpenL, new CMccDtmfUlStream" ) + + stream = CMccDtmfUlStream::NewLC( aStreamId, this, iMccResources, + iRtpmanager, aFourCC, aStreamType, *iRtpMediaClock ); + } + // Special handling for local video if it should be displayed (treat as uplink) + else if( sinkType == KMccRtpSinkUid || + localAVToDisplayStream ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::OpenL, new CMccSymUlStream" ) + stream = CMccSymUlStream::NewLC( aStreamId, + this, + iMccResources, + iRtpmanager, + aFourCC, + aStreamType, + *iRtpMediaClock ); + } + else if( sourceType == KMccRtpSourceUid && sinkType != KMccVideoSinkUid ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::OpenL, new CMccSymDlStream" ) + stream = CMccSymDlStream::NewLC( aStreamId, + this, + iMccResources, + iRtpmanager, + aStreamType ); + } + else if( ( sourceType == KMccRtpSourceUid && sinkType == KMccVideoSinkUid ) || + ( aStreamType == KMccAudioLocalStream || aStreamType == KMccVideoLocalStream ) ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::OpenL, new CMccSymSimpleDlStream" ) + stream = CMccSymSimpleDlStream::NewLC( aStreamId, + this, + iMccResources, + iRtpmanager, + aFourCC, + aStreamType ); + + } + else + { + __SUBCONTROLLER( "CMccSymSubthreadClient::OpenL, KErrArgument" ) + User::Leave( KErrArgument ); + } + + stream->AddSinkAndSourceL( aDatasink, aDatasource ); + iStreams.AppendL( stream ); + CleanupStack::Pop( stream ); + + TInt index = FindStreamL( aStreamId ); + iStreams[ index ]->SetMMFPriority( aSettings ); + + __SUBCONTROLLER( "CMccSymSubthreadClient::OpenL, exit" ) + } + + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::PrepareL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::PrepareL( const TUint32 aStreamId, + const TUint32 aEndpointId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::PrepareL, streamId", aStreamId ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::PrepareL, aEndpointId", aEndpointId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->PrimeL( aEndpointId ); + __SUBCONTROLLER( "CMccSymSubthreadClient::PrepareL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::PlayL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::PlayL( const TUint32 aStreamId, + const TUint32 aEndpointId, + TBool aStreamPaused, + TBool aEnableRTCP ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::PlayL, streamId", aStreamId ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::PlayL, aEndpointId", aEndpointId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->PlayL( aEndpointId, aStreamPaused, aEnableRTCP ); + __SUBCONTROLLER( "CMccSymSubthreadClient::PlayL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::StopL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::StopL( const TUint32 aStreamId, + const TUint32 aEndpointId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::StopL, streamId", aStreamId ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::StopL, aEndpointId", aEndpointId ) + TInt index = FindStream( aStreamId ); + if ( index != KErrNotFound ) + { + iStreams[index]->StopL( aEndpointId ); + } + else + { + // No need to stop if unused + index = iUnusedStreams.Find( aStreamId ); + __ASSERT_ALWAYS( index != KErrNotFound, User::Leave( KErrNotFound ) ); + } + __SUBCONTROLLER( "CMccSymSubthreadClient::StopL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::PauseL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::PauseL( const TUint32 aStreamId, + const TUint32 aEndpointId, + TBool aEnableRTCP ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::PauseL, streamId", aStreamId ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::PauseL, aEndpointId", aEndpointId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->PauseL( aEndpointId, aEnableRTCP ); + __SUBCONTROLLER( "CMccSymSubthreadClient::PauseL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::ResumeL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::ResumeL( const TUint32 aStreamId, + const TUint32 aEndpointId, + TBool aEnableRTCP ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::ResumeL, streamId", aStreamId ) + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::ResumeL, aEndpointId", aEndpointId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->ResumeL( aEndpointId, aEnableRTCP ); + __SUBCONTROLLER( "CMccSymSubthreadClient::ResumeL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::CloseL +// From CMccSubThreadClientBase +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::CloseL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::CloseL, streamId", aStreamId ) + + TInt index = FindStream( aStreamId ); + if ( index != KErrNotFound ) + { + CMccSymStreamBase* tmp = iStreams[index]; + iStreams.Remove( index ); + delete tmp; + } + else + { + index = iUnusedStreams.Find( aStreamId ); + __ASSERT_ALWAYS( index != KErrNotFound, User::Leave( KErrNotFound ) ); + + // Stream was already deleted + iUnusedStreams.Remove( index ); + } + + // No need to fail stream deletion if manager update fails + TRAP_IGNORE( iRtpmanager->UpdateL() ) + + __SUBCONTROLLER( "CMccSymSubthreadClient::CloseL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::CloseL +// Closes all links +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::CloseL() + { + __SUBCONTROLLER( "CMccSymSubthreadClient::CloseL" ) + + for ( TInt i = iStreams.Count() - 1; i >= 0; i-- ) + { + CMccSymStreamBase* tmp = iStreams[i]; + tmp->RemoveContext( 0 ); + iStreams.Remove( i ); + delete tmp; + } + __SUBCONTROLLER( "CMccSymSubthreadClient::CloseL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::StreamsExistsL +// ----------------------------------------------------------------------------- +TBool CMccSymSubthreadClient::StreamsExistsL() + { + if (iStreams.Count()) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SendMediaSignalL +// Send media signalling to uplink +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::SendMediaSignalL( const TMccEvent& aEvent ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SendMediaSignalL, streamId", aEvent.iStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aEvent.iStreamId ); + iStreams[index]->SendMediaSignalL( aEvent ); + __SUBCONTROLLER( "CMccSymSubthreadClient::SendMediaSignalL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccUlSubThreadClient::SendRTCPReceiverReportL +// Sends a RTCP receiver report +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::SendRTCPReceiverReportL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SendRTCPReceiverReportL, streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->SendRTCPReceiverReportL(); + __SUBCONTROLLER( "CMccSymSubthreadClient::SendRTCPReceiverReportL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccUlSubThreadClient::SendRTCPSenderReportL +// Sends a RTCP sender report +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::SendRTCPSenderReportL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SendRTCPSenderReportL, streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->SendRTCPSenderReportL(); + __SUBCONTROLLER( "CMccSymSubthreadClient::SendRTCPSenderReportL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SendRTCPDataL +// Sends Non-RTCP data +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::SendRTCPDataL( const TUint32 aStreamId, + const TDesC8& aData ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::SendRTCPDataL, streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->SendRTCPDataL( aData ); + __SUBCONTROLLER( "CMccSymSubthreadClient::SendRTCPDataL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccUlSubThreadClient::GetSupportedBitratesL +// Gets the supported bitrates from the codec of the specified stream +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::GetSupportedBitratesL( const TUint32 /*aStreamId*/, + RArray& /*aBitrates*/ ) + { + //TBI: What with the stream ID? + //TODO //User::LeaveIfError( iSubthread.GetSupportedBitrates( aBitrates ) ); + } + +// ----------------------------------------------------------------------------- +// CMccUlSubThreadClient::GetSSRCL +// Gets the syncronization source for the specified stream +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::GetSSRCL( const TUint32 aStreamId, TUint32& aSSRCValue ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetSSRCL, streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->GetSSRCL( aSSRCValue ); + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::GetSSRCL, SSRC", aSSRCValue ) + __SUBCONTROLLER( "CMccSymSubthreadClient::GetSSRCL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccDlSubThreadClient::StartInactivityTimerL +// Starts inactivity timer for a stream +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::StartInactivityTimerL( const TUint32 aStreamId, + TUint32 aTimeoutTime ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::StartInactivityTimerL, streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->StartInactivityTimerL( aTimeoutTime ); + __SUBCONTROLLER( "CMccSymSubthreadClient::StartInactivityTimerL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccDlSubThreadClient::StopInactivityTimerL +// Stops inactivity timer for a stream +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::StopInactivityTimerL( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::StopInactivityTimerL, streamId", aStreamId ) + __ASSERT_ALWAYS( iStreams.Count(), User::Leave( KErrNotFound ) ); + TInt index = FindStreamL( aStreamId ); + iStreams[index]->StopInactivityTimerL(); + __SUBCONTROLLER( "CMccSymSubthreadClient::StopInactivityTimerL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::GetFmtpAttrL +// Fetches the FMTP attribute of the current codec +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::GetFmtpAttrL( const TUint32 /*aStreamId*/, + TDes8& /*aFmtp*/ ) + { + + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SetRemoteAddressL +// Sets the remote address of uplink stream +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::SetRemoteAddressL( TInetAddr aRemAddr ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::SetRemoteAddressL" ) + __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) ); + + User::LeaveIfError( iRtpmanager->SetRemoteAddress( aRemAddr ) ); + + TInt strmCount = iStreams.Count(); + for( TInt k = 0; k < strmCount; k++ ) + { + iStreams[k]->ResetCountersL(); + } + __SUBCONTROLLER( "CMccSymSubthreadClient::SetRemoteAddressL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SetRemoteAddressL +// Sets the remote address of uplink stream +// ----------------------------------------------------------------------------- +void CMccSymSubthreadClient::SetRemoteRtcpAddrL( TInetAddr aRemAddr ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::SetRemoteRtcpAddrL" ) + __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) ); + + User::LeaveIfError( iRtpmanager->SetRemoteRtcpAddr( aRemAddr ) ); + + TInt strmCount = iStreams.Count(); + for( TInt k = 0; k < strmCount; k++ ) + { + iStreams[k]->ResetCountersL(); + } + __SUBCONTROLLER( "CMccSymSubthreadClient::SetRemoteRtcpAddrL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::InitializeLinkL +// Initializes the RTP session in the subthread +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::InitializeLinkL( TRequestStatus& aStatus, + TInt aIapId ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::InitializeLinkL" ) + __ASSERT_ALWAYS( !iSessionCreated, User::Leave( KErrAlreadyExists ) ); + iRtpmanager->InitializeL( aStatus, aIapId ); + __SUBCONTROLLER( "CMccSymSubthreadClient::InitializeLinkL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::CreateRtpSessionL +// Creates the RTP session in the subthread +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::CreateRtpSessionL( TUint aPort, + TBool aEnableRTCP, + TInt aIpTos, + CMccRtpMediaClock& aClock ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::CreateRtpSessionL" ) + iRtpMediaClock = &aClock; + + TBool secure( EFalse ); + if ( KMccLinkSecure == iLinkType || KMccLinkSecureVideo == iLinkType ) + { + secure = ETrue; + } + + TBool increaseDefaultSocketSize( EFalse ); + if ( KMccLinkGeneralVideo == iLinkType || KMccLinkSecureVideo == iLinkType ) + { + increaseDefaultSocketSize = ETrue; + } + + iRtpmanager->CreateSessionL( aPort, aEnableRTCP, secure, increaseDefaultSocketSize ); + iRtpmanager->SetIpTOS( aIpTos ); + iSessionCreated = ETrue; + + __SUBCONTROLLER( "CMccSymSubthreadClient::CreateRtpSessionL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SetAudioRouteL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::SetAudioRouteL( + TUint32 aStreamId, + TUint32 aRoutingDestination ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::SetAudioRouteL" ) + TInt index = FindStreamL( aStreamId ); + iStreams[ index ]->SetAudioRouteL( aRoutingDestination ); + __SUBCONTROLLER( "CMccSymSubthreadClient::SetAudioRouteL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::GetAudioRouteL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::GetAudioRouteL( + TUint32 aStreamId, + TUint32& aRoutingDestination ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::GetAudioRouteL" ) + TInt index = FindStreamL( aStreamId ); + iStreams[ index ]->GetAudioRouteL( aRoutingDestination ); + __SUBCONTROLLER( "CMccSymSubthreadClient::GetAudioRouteL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::UnuseL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::UnuseL( TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::UsuseL, streamId", aStreamId ) + + TInt index = FindStream( aStreamId ); + if ( index != KErrNotFound ) + { + CMccSymStreamBase* tmp = iStreams[index]; + iStreams.Remove( index ); + delete tmp; + + // Store stream id for later use (when stream is explicitly deleted) + iUnusedStreams.AppendL( aStreamId ); + } + else + { + index = iUnusedStreams.Find( aStreamId ); + __ASSERT_ALWAYS( index != KErrNotFound, User::Leave( KErrNotFound ) ); + } + + __SUBCONTROLLER( "CMccSymSubthreadClient::UsuseL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::GetLocalIpAddressesL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::GetLocalIpAddressesL( TMccCreateLink& aClientData ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::GetLocalIpAddressesL" ) + + iRtpmanager->GetLocalIpAddressesL( aClientData ); + + __SUBCONTROLLER( "CMccSymSubthreadClient::GetLocalIpAddressesL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SetParameterL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::SetParameterL( + TUint32 aParam, + TUint32 /*aStreamId*/, + TUint32 /*aEndpointId*/, + const TDesC8& aVal ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::SetParameterL" ) + + switch ( aParam ) + { + case KMccRtpCName: + { + iRtpmanager->SetCNameL( aVal ); + break; + } + default: + { + User::Leave( KErrNotSupported ); + break; + } + } + + __SUBCONTROLLER( "CMccSymSubthreadClient::SetParameterL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::GetParameterL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::GetParameterL( + TUint32 /*aParam*/, + TUint32 /*aStreamId*/, + TUint32 /*aEndpointId*/, + TDesC8& /*aVal*/ ) + { + } + + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::SendEventToClient +// ----------------------------------------------------------------------------- +// +TInt CMccSymSubthreadClient::SendEventToClient( const TMMFEvent& aEvent ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::SendEventToClient" ) + + // Do in a bit ackward way in order to save stack memory + TMccEvent* mccEventPtr = 0; + if ( IS_MCC_EVENT( aEvent ) ) + { + mccEventPtr = + reinterpret_cast( aEvent ).iMccEvent; + } + + if ( mccEventPtr ) + { + mccEventPtr->iLinkId = iLinkId; + + __SUBCONTROLLER_EVENT( (*mccEventPtr) ) + + TUid eventUid = aEvent.iEventType; + TUid amrUid = TUid::Uid( KDllUidAmrPayloadFormat ); + + // If RTCP BYE received remove crypto context + if ( KMccRtcpReceived == mccEventPtr->iEventType ) + { + const TMccRtcpEventData& eventdata = + (*reinterpret_cast( + &mccEventPtr->iEventData ))(); + + if ( KRtcpByePacket == eventdata.iRtcpPacketType ) + { + // Remove crypto context + const TInt count = iStreams.Count(); + for( TInt k = 0; k < count; k++ ) + { + // Ignore the return value as we're doing this blindly + iStreams[k]->RemoveContext( 0 ); + } + } + } + + if( amrUid == eventUid ) + { + // Amr events not forwarded + TInt err = HandleAmrEvent( aEvent, *mccEventPtr ); + __SUBCONTROLLER( "CMccSymSubthreadClient::SendEventToClient, exit" ) + return err; + } + + iObserver->SendMccEventToClient( *mccEventPtr ); + } + else + { + TMccEvent mccEvent; + DoMccEvent( mccEvent, aEvent ); + + __SUBCONTROLLER_EVENT( mccEvent ) + + iObserver->SendMccEventToClient( mccEvent ); + } + + __SUBCONTROLLER( "CMccSymSubthreadClient::SendEventToClient, exit" ) + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::DoMccEvent +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::DoMccEvent( + TMccEvent& aEvent, + const TMMFEvent& aMMFEvent ) + { + aEvent.iEventCategory = KMccEventCategoryStream; + aEvent.iEventType = KMccStreamMMFEvent; + aEvent.iErrorCode = aMMFEvent.iErrorCode; + aEvent.iLinkId = iLinkId; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::DataSink +// ----------------------------------------------------------------------------- +// +MDataSink* CMccSymSubthreadClient::DataSink( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::DataSink, streamId", aStreamId ) + TInt strmCount = iStreams.Count(); + if( strmCount ) + { + TInt index = this->FindStream( aStreamId ); + if ( index != KErrNotFound ) + { + return iStreams[index]->DataSink(); + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::DataSource +// ----------------------------------------------------------------------------- +// +MDataSource* CMccSymSubthreadClient::DataSource( const TUint32 aStreamId ) + { + __SUBCONTROLLER_INT1( "CMccSymSubthreadClient::DataSource, streamId", aStreamId ) + TInt strmCount = iStreams.Count(); + if( strmCount ) + { + TInt index = this->FindStream( aStreamId ); + if ( index != KErrNotFound ) + { + return iStreams[index]->DataSource(); + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::BindContextIntoStreamL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::BindContextIntoStreamL( TUint32 aStreamId, + TUint32 aEndpointId, + const TMccCryptoContext& aContextParams ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::BindContextIntoStreamL IN" ) + + TInt index = this->FindStreamL( aStreamId ); + + iStreams[ index ]->BindContextIntoStreamL( aEndpointId, aContextParams ); + + __SUBCONTROLLER( "CMccSymSubthreadClient::BindContextIntoStreamL END" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::RemoveContextL +// ----------------------------------------------------------------------------- +// +void CMccSymSubthreadClient::RemoveContextL( TUint32 aStreamId, + TUint32 aEndpointId ) + { + __SUBCONTROLLER( "CMccSymSubthreadClient::RemoveContextL IN" ) + + TInt index = this->FindStreamL( aStreamId ); + + iStreams[ index ]->RemoveContext( aEndpointId ); + + __SUBCONTROLLER( "CMccSymSubthreadClient::RemoveContextL END" ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSubthreadClient::HandleAmrEvent +// ----------------------------------------------------------------------------- +// +TInt CMccSymSubthreadClient::HandleAmrEvent( + const TMMFEvent& aEvent, + const TMccEvent& aMccEvent ) + { + const TInt internalEvent = + reinterpret_cast( aEvent ).iInternalEventType; + + const TMccAmrEventData& eventdata = + (*reinterpret_cast( + &aMccEvent.iEventData ))(); + + __SUBCONTROLLER_INT1( "CMccSymStreamBase::HandleAmrEvent AMR EVENT:", + internalEvent ); + __SUBCONTROLLER_INT1( "CMccSymStreamBase::HandleAmrEvent AMR MODE_REQ BITRATE:", + eventdata.iModeRequestBitrate ); + + if ( EMccInternalAmrEventCmr == internalEvent ) + { + if ( eventdata.iModeRequestBitrate > 0 ) + { + // Mode change request, forward it to other streams + const TInt count = iStreams.Count(); + for( TInt k = 0; k < count; k++ ) + { + // Ignore the return value as we're doing this blindly + iStreams[k]->ChangeBitrate( eventdata.iModeRequestBitrate ); + } + } + } + return KErrNone; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File