--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccsubcontroller/src/mccdtmfdlstream.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,524 @@
+/*
+* Copyright (c) 2006-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: Provides DTMF support
+*
+*/
+
+
+
+
+#include <mmf/server/mmfformat.h>
+#include "mccdtmfdlstream.h"
+#include "mccsubcontrollerlogs.h"
+#include "mccdatasource.h"
+#include "mcccodecconfigurator.h"
+#include "mccrtpmanager.h"
+#include "mccrtpmediaclock.h"
+#include "mccmultiplexer.h"
+#include "mccresources.h"
+#include "mccinternaldef.h"
+#include "mccrtpdatasource.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that might leave.
+// ---------------------------------------------------------------------------
+//
+CMccDtmfDlStream::CMccDtmfDlStream( TUint32 aMccStreamId,
+ MAsyncEventHandler* aEventhandler, MMccResources* aMccResources,
+ CMccRtpManager* aManager, TFourCC aFourCC, TInt aStreamType,
+ CMccRtpMediaClock& aClock )
+ :
+ CMccSymStreamBase( aMccStreamId, aEventhandler, aMccResources, aManager,
+ aStreamType ), iFourCC( aFourCC )
+ {
+ iRtpMediaClock = &aClock;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::ConstructL()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::ConstructL" )
+ __SUBCONTROLLER( "CMccDtmfDlStream::ConstructL, exit" )
+ }
+
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CMccDtmfDlStream* CMccDtmfDlStream::NewL( TUint32 aMccStreamId,
+ MAsyncEventHandler* aEventHandler, MMccResources* aMccResources,
+ CMccRtpManager* aManager, TFourCC aFourCC, TInt aStreamType,
+ CMccRtpMediaClock& aClock )
+ {
+ CMccDtmfDlStream* self = CMccDtmfDlStream::NewLC( aMccStreamId, aEventHandler,
+ aMccResources, aManager, aFourCC, aStreamType, aClock );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CMccDtmfDlStream* CMccDtmfDlStream::NewLC( TUint32 aMccStreamId,
+ MAsyncEventHandler* aEventHandler, MMccResources* aMccResources,
+ CMccRtpManager* aManager, TFourCC aFourCC, TInt aStreamType,
+ CMccRtpMediaClock& aClock )
+ {
+ CMccDtmfDlStream* self = new( ELeave ) CMccDtmfDlStream( aMccStreamId,
+ aEventHandler, aMccResources, aManager, aFourCC, aStreamType, aClock );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CMccDtmfDlStream::~CMccDtmfDlStream()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::~CMccDtmfDlStream" )
+
+ // Must do mux cleanup before decoder (mux sink) deletion
+ MultiplexerCleanup();
+
+ if ( iFormatDecode )
+ {
+ iFormatDecode->SourceThreadLogoff();
+ delete iFormatDecode;
+ }
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::~CMccDtmfDlStream, exit" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Sets the MMF priority settings for this stream.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::SetPrioritySettingsL(
+ const TMMFPrioritySettings& aPriority )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::SetPrioritySettingsL start" );
+
+ if ( iFormatDecode )
+ {
+ iFormatDecode->SetSourcePrioritySettings( aPriority );
+ }
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::SetPrioritySettingsL end ");
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Adds the sink and source to the stream.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::AddSinkAndSourceL( MDataSink* aDataSink,
+ MDataSource* aDataSource )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::AddSinkAndSourceL" )
+ __ASSERT_ALWAYS( aDataSink && aDataSource, User::Leave( KErrArgument ) );
+
+ __ASSERT_ALWAYS( aDataSink->DataSinkType() == KMccAnySinkUid,
+ User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( aDataSource->DataSourceType() == KMccRtpSourceUid,
+ User::Leave( KErrArgument ) );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::AddSinkAndSourceL, adding" )
+ iDatasink = aDataSink;
+ iDatasource = aDataSource;
+
+ iMultiplexer = iMccResources->MultiplexerL( iDatasource );
+
+ User::LeaveIfError( iDatasink->SinkThreadLogon( *this ) );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::AddSinkAndSourceL, exit" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Loads a codec to the stream.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::LoadCodecL( const TMccCodecInfo& aCodecInfo,
+ const TDesC8& aFmtp )
+ {
+ __SUBCONTROLLER_INT1( "CMccDtmfDlStream::LoadCodecL, codec state:",
+ CurrentCodecState() )
+
+ __ASSERT_ALWAYS( CurrentCodecState() == EStateCodecNone ||
+ iCodecInfo.iFourCC == aCodecInfo.iFourCC,
+ User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( iDatasink, User::Leave( KErrNotReady ) );
+
+ iCodecInfo = aCodecInfo;
+
+ if ( CurrentCodecState() == EStateCodecNone )
+ {
+ delete iFmtpAttr;
+ iFmtpAttr = NULL;
+
+ iFmtpAttr = HBufC8::NewL( aFmtp.Length() );
+ iFmtpAttr->Des().Copy( aFmtp );
+
+ iCodecInfo.iFmtpLength = iFmtpAttr->Length();
+ CreatePayloadFormatDecoderL();
+
+ iMultiplexer->NegotiateSourceL( *iFormatDecode );
+
+ SetCodecState( EStateCodecNegotiated );
+ }
+ else if ( CurrentCodecState() == EStateCodecNegotiated )
+ {
+ SetCodecState( EStateCodecLoaded );
+
+ // Codec is not fully usable yet, do just formatter initialization
+ MccCodecConfigurator::ConfigureCodecL( *iFormatDecode,
+ *iDatasink,
+ iCodecInfo,
+ *iRtpMediaClock,
+ CurrentCodecState() );
+ }
+ else if ( CurrentCodecState() == EStateCodecLoaded ||
+ CurrentCodecState() == EStateCodecLoadedAndUpdating )
+ {
+ // Update codec info
+ SetCodecState( EStateCodecLoadedAndUpdating );
+ UpdateCodecInformationL( iCodecInfo );
+ }
+ else
+ {
+ User::Leave( KErrNotReady );
+ }
+
+ __SUBCONTROLLER_INT1( "CMccDtmfDlStream::LoadCodecL, exit, new state:",
+ CurrentCodecState() )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Primes the stream ready.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::PrimeL( const TUint32 aEndpointId )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::PrimeL" )
+ __ASSERT_ALWAYS( iFormatDecode, User::Leave( KErrNotReady ) );
+
+ TBool controlNetworkResources = SetStateL( EStatePrepared, aEndpointId );
+
+ if ( controlNetworkResources )
+ {
+ iRtpmanager->CreateReceiveStreamL( *iDatasource, iCodecInfo );
+ }
+
+ LoadCodecL( iCodecInfo, KNullDesC8 );
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasink ) ) )
+ {
+ iDatasink->SinkPrimeL();
+ }
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasource ) ) )
+ {
+ iFormatDecode->SourcePrimeL();
+ }
+
+ InformStreamStateChange( KMccStreamPrepared, aEndpointId );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::PrimeL, exit" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Starts the stream. DTMF can be now sent and received.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::PlayL(
+ const TUint32 aEndpointId,
+ TBool /*aStreamPaused*/,
+ TBool /*aEnableRtcp*/ )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::PlayL" )
+ __ASSERT_ALWAYS( iFormatDecode && iDatasource && iDatasink,
+ User::Leave( KErrNotReady ) );
+
+ TBool controlNetworkResources = SetStateL( EStateStreaming, aEndpointId );
+
+ if ( controlNetworkResources )
+ {
+ iRtpmanager->StartSessionL();
+ }
+
+ LoadCodecL( iCodecInfo, KNullDesC8 );
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasink ) ) )
+ {
+ iDatasink->SinkPlayL();
+ }
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasource ) ) )
+ {
+ iFormatDecode->SourcePlayL();
+ }
+
+ // Dtmf does not need standby, deactivate it
+ CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+ dSource->StandBy( EDeactivateStandby, iCodecInfo.iPayloadType );
+
+ InformStreamStateChange( KMccStreamStarted, aEndpointId );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::PlayL, exit" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Pauses the stream. DTMF sending and receiving are not possible in paused
+// state.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::PauseL( const TUint32 aEndpointId, TBool /*aEnableRtcp*/ )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::PauseL" )
+ __ASSERT_ALWAYS( iFormatDecode && iDatasource && iDatasink,
+ User::Leave( KErrNotReady ) );
+
+ SetStateL( EStatePaused, aEndpointId );
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasink ) ) )
+ {
+ iDatasink->SinkPauseL();
+ }
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasource ) ) )
+ {
+ iFormatDecode->SourcePauseL();
+ }
+
+ InformStreamStateChange( KMccStreamPaused, aEndpointId );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::PauseL, exit" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Resumes the stream.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::ResumeL( const TUint32 aEndpointId, TBool /*aEnableRtcp*/ )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::ResumeL" )
+ __ASSERT_ALWAYS( iFormatDecode && iDatasource && iDatasink,
+ User::Leave( KErrNotReady ) );
+
+ SetStateL( EStateStreaming, aEndpointId );
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasink ) ) )
+ {
+ iDatasink->SinkPlayL();
+ }
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasource ) ) )
+ {
+ iFormatDecode->SourcePlayL();
+ }
+
+ InformStreamStateChange( KMccStreamResumed, aEndpointId );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::ResumeL, exit" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Stops the stream.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::StopL( const TUint32 aEndpointId )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::StopL" )
+ __ASSERT_ALWAYS( iFormatDecode && iDatasource && iDatasink,
+ User::Leave( KErrNotReady ) );
+
+ SetStateL( EStateStopped, aEndpointId );
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasink ) ) )
+ {
+ iDatasink->SinkStopL();
+ }
+
+ if ( IsControlled( MCC_ENDPOINT_ID( iDatasource ) ) )
+ {
+ iFormatDecode->SourceStopL();
+ }
+
+ InformStreamStateChange( KMccStreamStopped, aEndpointId );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::StopL, exit" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Resets jitterbuffer.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::ResetCountersL()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::ResetCountersL - NO_OP" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Sets the current record/play balance depending on the stream type.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::SetBalanceL( TInt /*aLeftbal*/, TInt /*aRightbal*/ )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::SetBalanceL - NO_OP" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Gets the current record/play balance depending on the stream type
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::GetBalanceL( TInt& /*aLeftbal*/, TInt& /*aRightbal*/ )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::GetBalanceL - NO_OP" )
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Starts inactivity timer for a stream in a given session.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::StartInactivityTimerL( TUint32 /*aTimeoutTime*/ )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::StartInactivityTimerL - NO_OP" )
+ // TBD: Should be pointed once to the RTP source endpoint
+ };
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Stops inactivity timer for a stream in a given session.
+// ---------------------------------------------------------------------------
+void CMccDtmfDlStream::StopInactivityTimerL()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::StopInactivityTimerL - NO_OP" )
+ // TBD: Should be pointed once to the RTP source endpoint
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+// Get synchronization source identifier used by this stream.
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::GetSSRCL( TUint32& /*aSSRCValue*/ )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::GetSSRCL" )
+
+ User::Leave( KErrNotSupported );
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+//
+// ---------------------------------------------------------------------------
+//
+TBool CMccDtmfDlStream::IsUplink()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::IsUplink" )
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// From class CMccSymStreamBase.
+//
+// ---------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::StandByL()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::StandByL" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccDtmfDlStream::CreatePayloadFormatDecoderL
+// Creates a payload format decoder for DTMF payload decoding.
+// -----------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::CreatePayloadFormatDecoderL()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::CreatePayloadFormatDecoderL" )
+ __ASSERT_ALWAYS( iMultiplexer, User::Leave( KErrNotReady ) );
+ __ASSERT_ALWAYS( NULL == iFormatDecode, User::Leave( KErrAlreadyExists ) );
+
+ TUid formatuid;
+ formatuid.iUid = static_cast<TInt32>( iCodecInfo.iPayloadFormatDecoder );
+ iFormatDecode = CMMFFormatDecode::NewL( formatuid, iMultiplexer );
+ iFormatDecode->SetSourceDataTypeCode( iCodecInfo.iFourCC, Type() );
+
+ User::LeaveIfError( iFormatDecode->SourceThreadLogon( *this ) );
+ iFormatDecode->SetSourcePrioritySettings( iPrioritySettings );
+
+ User::LeaveIfError(
+ iMultiplexer->MultiplexerSourceThreadLogon(
+ *this, *iFormatDecode, ETrue, Type(), EFalse ) );
+
+ RArray<TUint> payloads;
+ CleanupClosePushL( payloads );
+ ParsePayloadTypesL( payloads, iCodecInfo );
+ iMultiplexer->RegClientForPayloadsL( *iFormatDecode, payloads );
+ CleanupStack::PopAndDestroy( &payloads );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::CreatePayloadFormatDecoderL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccDtmfDlStreams::UpdateCodecInformationL
+// Updates codec parameters dynamically.
+// -----------------------------------------------------------------------------
+//
+void CMccDtmfDlStream::UpdateCodecInformationL( TMccCodecInfo& aCodecInfo )
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::UpdateCodecInformationL" )
+ __ASSERT_ALWAYS( iFormatDecode, User::Leave( KErrNotReady ) );
+ __ASSERT_ALWAYS( iDatasink, User::Leave( KErrNotReady ) );
+
+ MccCodecConfigurator::ConfigureCodecL( *iFormatDecode,
+ *iDatasink, aCodecInfo, *iRtpMediaClock, CurrentCodecState() );
+
+ __SUBCONTROLLER( "CMccDtmfDlStream::UpdateCodecInformationL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccDtmfDlStream::MultiplexerSink
+// -----------------------------------------------------------------------------
+//
+MDataSink* CMccDtmfDlStream::MultiplexerSink()
+ {
+ __SUBCONTROLLER( "CMccDtmfDlStream::MultiplexerSink" )
+ return iFormatDecode;
+ }