diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccsubcontroller/src/mccsymsimpledlstream.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccsubcontroller/src/mccsymsimpledlstream.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,606 @@ +/* +* 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: MCP Symmetric subthread downlink stream +* +*/ + + + +// INCLUDE FILES +#include +#include +#include "mccsymsimpledlstream.h" +#include "mccdldatapath.h" +#include "mccjitterbuffer.h" +#include "mccuids.hrh" +#include "mccrtpmanager.h" +#include "mcccodecconfigurator.h" +#include "mccinternaldef.h" +#include "mccvideosink.h" +#include "mccsubcontrollerlogs.h" +#include "mccmultiplexer.h" +#include "mccresources.h" + +// CONSTANTS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::CMccSymSimpleDlStream +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMccSymSimpleDlStream::CMccSymSimpleDlStream( + TUint32 aMccStreamId, + MAsyncEventHandler* aEventhandler, + MMccResources* aMccResources, + CMccRtpManager* aManager, + TFourCC aFourCC, + TInt aStreamType ) : + CMccSymStreamBase( aMccStreamId, + aEventhandler, + aMccResources, + aManager, + aStreamType ) + { + iFourCC = aFourCC; + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CMccSymSimpleDlStream* CMccSymSimpleDlStream::NewLC( + TUint32 aMccStreamId, + MAsyncEventHandler* aEventhandler, + MMccResources* aMccResources, + CMccRtpManager* aManager, + TFourCC aFourCC, + TInt aStreamType ) + { + CMccSymSimpleDlStream* s = + new ( ELeave ) CMccSymSimpleDlStream( aMccStreamId, + aEventhandler, + aMccResources, + aManager, + aFourCC, + aStreamType ); + CleanupStack::PushL( s ); + s->ConstructL(); + + return s; + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::ConstructL() + { + iDatapath = CMccDlDataPath::NewL( this, iMccResources, Type() ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::~CMccSymSimpleDlStream +// Destructor +// ----------------------------------------------------------------------------- +// +CMccSymSimpleDlStream::~CMccSymSimpleDlStream() + { + if( iSoundDevice ) + { + iSoundDevice = NULL; + } + + // Must do mux cleanup before decoder (mux sink) deletion + MultiplexerCleanup(); + + if( iFormatDecode ) + { + iFormatDecode->SourceThreadLogoff(); + delete iFormatDecode; + iFormatDecode = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::SetPrioritySettingsL +// Sets the MMF priority settings for this stream +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::SetPrioritySettingsL( + const TMMFPrioritySettings& aPriority ) + { + __ASSERT_ALWAYS( iDatasink, User::Leave( KErrNotReady ) ); + + iDatasink->SetSinkPrioritySettings( aPriority ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::AddSinkAndSourceL +// From CMccSymStreamBase +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::AddSinkAndSourceL( + MDataSink* aDatasink, + MDataSource* aDatasource ) + { + __ASSERT_ALWAYS( aDatasink && aDatasource, User::Leave( KErrArgument ) ); + + iDatasink = aDatasink; + iDatasource = aDatasource; + + iMultiplexer = iMccResources->MultiplexerL( iDatasource ); + + // Inform datapath about ids of associated sink and source + iDatapath->SetAssociatedSink( iDatasink ); + iDatapath->SetAssociatedSource( iDatasource ); + + iDatapath->AddDataSinkL( aDatasink ); + + User::LeaveIfError( iDatasink->SinkThreadLogon( *this ) ); + + iDatapath->AddDataSourceL( aDatasource ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::LoadCodecL +// From CMccSymStreamBase +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::LoadCodecL( + const TMccCodecInfo& aCodecInfo, + const TDesC8& aFmtp ) + { + __SUBCONTROLLER_INT1( "CMccSymSimpleDlStream::LoadCodecL, codec state:", + CurrentCodecState() ) + + __ASSERT_ALWAYS( CurrentCodecState() == EStateCodecNone || + iCodecInfo.iFourCC == aCodecInfo.iFourCC, + User::Leave( KErrArgument ) ); + + iCodecInfo = aCodecInfo; + + if ( CurrentCodecState() == EStateCodecNone ) + { + delete iFmtpAttr; + iFmtpAttr = NULL; + + iFmtpAttr = HBufC8::NewL( aFmtp.Length() ); + iFmtpAttr->Des().Copy( aFmtp ); + + iCodecInfo.iFmtpLength = iFmtpAttr->Length(); + CreatePayloadFormatDecoderL(); + + // Just negotiate the codec, load it later + static_cast( iDatapath )->NegotiateL( *iFormatDecode ); + + SetCodecState( EStateCodecNegotiated ); + } + else if ( CurrentCodecState() == EStateCodecNegotiated ) + { + // Codec is not fully usable yet, do just formatter initialization + MccCodecConfigurator::ConfigureCodecL( *iFormatDecode, + *iDatasink, + aCodecInfo, + *iRtpMediaClock, + CurrentCodecState() ); + + MccCodecConfigurator::ConfigureCodecL( *iDatasource, + *iDatasink, + iCodecInfo, + *iRtpMediaClock, + CurrentCodecState() ); + + SetCodecState( EStateCodecPrepared ); + } + else if ( CurrentCodecState() == EStateCodecPrepared ) + { + if ( CodecLoadingAllowed() ) + { + // Load the codec + static_cast( iDatapath )->LoadL( *iFormatDecode ); + + // Set state before updating as the state affects to update functionality + SetCodecState( EStateCodecLoaded ); + + UpdateCodecInformationL( iCodecInfo ); + } + } + else if ( CurrentCodecState() == EStateCodecLoaded || + CurrentCodecState() == EStateCodecLoadedAndUpdating ) + { + // Update codec info + if ( iDatasource->DataSourceType() == KMccRtpSourceUid ) + { + CMccRtpDataSource* dataSource = + static_cast( iDatasource ); + + // For updating keep alive parameters + TMccCodecInfoBuffer infoBuffer( iCodecInfo ); + dataSource->ConfigureL( infoBuffer ); + } + SetCodecState( EStateCodecLoadedAndUpdating ); + UpdateCodecInformationL( iCodecInfo ); + } + else + { + User::Leave( KErrNotReady ); + } + + __SUBCONTROLLER_INT1( "CMccSymSimpleDlStream::LoadCodecL, exit, new state:", + CurrentCodecState() ) + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::UpdateCodecInformationL +// From CMccSymStreamBase +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::UpdateCodecInformationL( TMccCodecInfo& aCodecInfo ) + { + __ASSERT_ALWAYS( iFormatDecode, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatasink, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) ); + + HandleSpecialSinksAndSources(); + + iCodecInfo.iIsUpdate = ETrue; + + // Configure the decoder + MccCodecConfigurator::ConfigureCodecL( *iFormatDecode, + *iDatasink, + aCodecInfo, + *iRtpMediaClock, + CurrentCodecState() ); + + // Configure also the real source + MccCodecConfigurator::ConfigureCodecL( *iDatasource, + *iDatasink, + iCodecInfo, + *iRtpMediaClock, + CurrentCodecState() ); + } + + +// ----------------------------------------------------------------------------- +// CMccSymDlStream::CreatePayloadFormatDecoderL +// Creates the payload format decoder +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::CreatePayloadFormatDecoderL() + { + __ASSERT_ALWAYS( iMultiplexer, User::Leave( KErrArgument ) ); + + TUid formatuid; + CMMFFormatDecode* tmp = NULL; + + formatuid.iUid = KImplUidAnyPayloadFormatDecode; + + // Multiplexer is the source of the decoder + tmp = CMMFFormatDecode::NewL( formatuid, iMultiplexer ); + + tmp->SetSourceDataTypeCode( iCodecInfo.iFourCC, Type() ); + + if( iFormatDecode ) + { + // Remove old one from multiplexer + iMultiplexer->MultiplexerSourceThreadLogoff( iFormatDecode ); + + iFormatDecode->SourceThreadLogoff(); + delete iFormatDecode; + } + + iFormatDecode = tmp; + User::LeaveIfError( iFormatDecode->SourceThreadLogon( *this ) ); + + // Add decoder as sink of the multiplexer + User::LeaveIfError( + iMultiplexer->MultiplexerSourceThreadLogon( *this, *iFormatDecode, ETrue, Type() ) ); + + if ( KMccRtpSourceUid == iDatasource->DataSourceType() ) + { + RArray payloads; + CleanupClosePushL( payloads ); + ParsePayloadTypesL( payloads, iCodecInfo ); + iMultiplexer->RegClientForPayloadsL( *iFormatDecode, payloads ); + CleanupStack::PopAndDestroy( &payloads ); + } + } + +// ----------------------------------------------------------------------------- +// CMccSymDlStream::PrimeL +// Primes the audio stream ready +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::PrimeL( const TUint32 aEndpointId ) + { + __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) ); + + TBool controlNetworkResources = SetStateL( EStatePrepared, aEndpointId ); + + if ( controlNetworkResources && !LocalStream() ) + { + iRtpmanager->CreateReceiveStreamL( *iDatasource, iCodecInfo ); + } + + LoadCodecL( iCodecInfo, KNullDesC8 ); + + DoPrimeL(); + + InformStreamStateChange( KMccStreamPrepared, aEndpointId ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::PlayL +// Starts audio streaming +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::PlayL( + const TUint32 aEndpointId, + TBool /*aStreamPaused*/, + TBool aEnableRtcp ) + { + __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) ); + + TBool controlNetworkResources = SetStateL( EStateStreaming, aEndpointId ); + + if ( !LocalStream() ) + { + if ( controlNetworkResources ) + { + iRtpmanager->StartSessionL(); + } + + User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) ); + } + + UpdateCodecLoadingPermission( ETrue ); + + LoadCodecL( iCodecInfo, KNullDesC8 ); + + DoPlayL(); + + InformStreamStateChange( KMccStreamStarted, aEndpointId ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::PauseL +// Pauses audio streaming +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::PauseL( const TUint32 aEndpointId, TBool aEnableRtcp ) + { + __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) ); + + SetStateL( EStatePaused, aEndpointId ); + + if ( !LocalStream() ) + { + User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) ); + } + + DoPauseL(); + + InformStreamStateChange( KMccStreamPaused, aEndpointId ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::ResumeL +// Resumes paused audio streaming +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::ResumeL( const TUint32 aEndpointId, TBool aEnableRtcp ) + { + __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) ); + + SetStateL( EStateStreaming, aEndpointId ); + + if ( !LocalStream() ) + { + User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) ); + } + + DoResumeL(); + + InformStreamStateChange( KMccStreamResumed, aEndpointId ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::StopL +// Stops the audio streaming +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::StopL( const TUint32 aEndpointId ) + { + __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) ); + + SetStateL( EStateStopped, aEndpointId ); + + DoStopL(); + + InformStreamStateChange( KMccStreamStopped, aEndpointId ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::SetBalanceL +// Sets the current play balance +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::SetBalanceL( TInt aLeftBal, TInt aRightBal ) + { + if( !iSoundDevice ) + { + User::Leave( KErrNotReady ); + } + else + { + iSoundDevice->SetPlayBalanceL( aLeftBal, aRightBal ); + } + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::GetBalanceL +// Returns the current play balance +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::GetBalanceL( TInt& aLeftbal, TInt& aRightbal ) + { + if( !iSoundDevice ) + { + User::Leave( KErrNotReady ); + } + else + { + iSoundDevice->GetPlayBalanceL( aLeftbal, aRightbal ); + } + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::GetSSRCL +// Returns SSRC value +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::GetSSRCL( TUint32& /*aSSRCValue*/ ) + { + User::Leave ( KErrNotSupported ); + } + + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::ResetCountersL +// Resets Jitterbuffer +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::ResetCountersL( ) + { + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::SendMediaSignalL +// Downlink can send RTCP media signals (only receiver reports) +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::SendMediaSignalL( const TMccEvent& aEvent ) + { + __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatasource, User::Leave( KErrNotReady ) ); + + CMccRtpDataSource* p = static_cast( iDatasource ); + p->SendMediaSignallingL( aEvent ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::SendRTCPReceiverReportL +// Sends a RTCP receiver report +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::SendRTCPReceiverReportL() + { + __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) ); + + CMccRtpDataSource* dSource = static_cast( iDatasource ); + User::LeaveIfError( dSource->SendRTCPReceiverReport() ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::StartInactivityTimerL +// Starts inactivity timer for a stream +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::StartInactivityTimerL( TUint32 aTimeoutTime ) + { + __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) ); + + CMccRtpDataSource* dSource = static_cast( iDatasource ); + dSource->StartInactivityTimerL( aTimeoutTime ); + } + + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::StopInactivityTimerL +// Stops inactivity timer for a stream +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::StopInactivityTimerL() + { + __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) ); + + CMccRtpDataSource* dSource = static_cast( iDatasource ); + dSource->StopInactivityTimerL( ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::IsUplink +// ----------------------------------------------------------------------------- +// +TBool CMccSymSimpleDlStream::IsUplink() + { + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::StandByL +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::StandByL() + { + __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) ); + + CMccRtpDataSource* dSource = static_cast( iDatasource ); + dSource->StandBy( EForceStandby, iCodecInfo.iPayloadType ); + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::JitterBufferError +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::JitterBufferError( TInt /*aError*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CMccSymDlStream::DynamicBufferChangeRequest +// ----------------------------------------------------------------------------- +// +void CMccSymSimpleDlStream::DynamicBufferChangeRequest( TInt /* aBufferSize*/ ) + { + + } + +// ----------------------------------------------------------------------------- +// CMccSymSimpleDlStream::MultiplexerSink +// ----------------------------------------------------------------------------- +// +MDataSink* CMccSymSimpleDlStream::MultiplexerSink() + { + return iFormatDecode; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File