/*
* 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 <mmf/server/mmfdatasource.h>
#include <mmf/server/mmfdatasink.h>
#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<TUint>& /*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<const TMccInternalEvent&>( 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<const TMccRtcpEventDataPackage*>(
&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<const TMccInternalEvent&>( aEvent ).iInternalEventType;
const TMccAmrEventData& eventdata =
(*reinterpret_cast<const TMccAmrEventDataPackage*>(
&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