diff -r 33a5d2bbf6fc -r 73a1feb507fb mmsharing/mmshengine/src/musengtwowaysession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsharing/mmshengine/src/musengtwowaysession.cpp Tue Aug 31 15:12:07 2010 +0300 @@ -0,0 +1,530 @@ +/* +* Copyright (c) 2005 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: +* +*/ + + +// USER +#include "musengtwowaysession.h" +#include "musunittesting.h" +#include "musengmceutils.h" +#include "musenglogger.h" +#include "musengremotevideoplayer.h" +#include "musenglivevideoplayer.h" + +// SYSTEM +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const TInt KMusEngJitterBufferLength = 51; //Must be bigger than treshold +// Using following value increases treshold buffer to 1 second from +// default 100 ms +const TInt KMusEngJitterBufferTreshold = 50; + +const TUint32 KMusEngTwoWayReceivingActivityTimeout = 5000; // 5 seconds +// 6 seconds keepalive timer, needs to be more than receiving timeout +const TUint8 KMusEngTwoWayRtpKeepAliveTimer = 6; + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusEngTwoWaySession* CMusEngTwoWaySession::NewL() + { + CMusEngTwoWaySession* self = new( ELeave )CMusEngTwoWaySession(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusEngTwoWaySession::~CMusEngTwoWaySession() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::~CMusEngTwoWaySession()" ) + + delete iRemoteVideoPlayer; + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::~CMusEngTwoWaySession()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::EnableDisplayL( TBool aEnable ) + { + MUS_LOG1( "mus: [ENGINE] -> CMusEngTwoWaySession::EnableDisplayL() %d", + aEnable ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplay( *iSession ); + if ( display ) + { + MusEngMceUtils::DoEnableDisplayL( *display, aEnable ); + } + CMceDisplaySink* vfDisplay = MusEngMceUtils::GetDisplayL( *iSession, ETrue ); + MusEngMceUtils::DoEnableDisplayL( *vfDisplay, aEnable ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::EnableDisplayL()") + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::SetOrientationL( TDisplayOrientation aOrientation ) + { + MUS_LOG1( "mus: [ENGINE] -> CMusEngTwoWaySession::SetOrientationL() %d", + aOrientation ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplay( *iSession ); + CMceDisplaySink* vfDisplay = MusEngMceUtils::GetDisplayL( *iSession, ETrue ); + + CMceDisplaySink::TRotation rotation = ( aOrientation == EPortrait ) ? + CMceDisplaySink::ENone : CMceDisplaySink::EClockwise90Degree; + + vfDisplay->SetRotationL( rotation ); + if ( display ) + { + display->SetRotationL( rotation ); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::SetOrientationL()" ) + } + +// ----------------------------------------------------------------------------- +// From MLcFileControl +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::EnableLcFileL( TBool /*aEnable*/ ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::EnableLcFileL" ) + + User::Leave( KErrNotSupported ); + + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::EnableLcFileL" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::SetRectsL( + const TRect& aRemoteRect, + const TRect& aLocalRect ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::SetRectsL()" ) + + iLocalRect = aLocalRect; + iRect = aRemoteRect; + RectChangedL(); + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::SetRectsL()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::SetSecondaryRectL( const TRect& aSecondaryRect ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::SetSecondaryRectL()" ) + + iLocalRect = aSecondaryRect; + RectChangedL(); + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::SetSecondaryRectL()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TRect CMusEngTwoWaySession::SecondaryRect() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::SecondaryRect()" ) + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::SecondaryRect()" ) + return iLocalRect; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TBool CMusEngTwoWaySession::IsDisplayEnabled() + { + TBool enabled( EFalse ); + if ( iSession ) + { + CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplay( *iSession ); + if ( !display ) + { + display = MusEngMceUtils::GetVfDisplay( *iSession ); + } + if ( display ) + { + enabled = display->IsEnabled(); + } + } + return enabled; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TBool CMusEngTwoWaySession::IsDisplayActive() + { + return ( IsDisplayEnabled() && iReceiving ); + } + +// ----------------------------------------------------------------------------- +// From MLcSession +// ----------------------------------------------------------------------------- +// +MLcVideoPlayer* CMusEngTwoWaySession::RemoteVideoPlayer() + { + return iRemoteVideoPlayer; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::RectChangedL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::RectChangedL()" ) + + // If session is not yet created, do nothing + if ( iSession && iSession->State() != CMceSession::ETerminated ) + { + TRect remoteRect( Rect() ); + MUS_LOG2( "mus: [ENGINE] remote tl.ix=%d tl.iy=%d", + remoteRect.iTl.iX, remoteRect.iTl.iY ) + MUS_LOG2( "mus: [ENGINE] remote br.ix=%d br.iy=%d", + remoteRect.iBr.iX, remoteRect.iBr.iY ) + MUS_LOG2( "mus: [ENGINE] local tl.ix=%d tl.iy=%d", + iLocalRect.iTl.iX, iLocalRect.iTl.iY ) + MUS_LOG2( "mus: [ENGINE] local br.ix=%d br.iy=%d", + iLocalRect.iBr.iX, iLocalRect.iBr.iY ) + + if ( remoteRect != iSetRemoteRect ) + { + CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplay( *iSession ); + if ( display ) + { + MUS_LOG( "mus: [ENGINE] set remote rect" ) + display->SetDisplayRectL( remoteRect ); + iSetRemoteRect = remoteRect; + } + } + + if ( iLocalRect != iSetLocalRect ) + { + MUS_LOG( "mus: [ENGINE] set local rect" ) + CMceDisplaySink* vfDisplay = MusEngMceUtils::GetDisplayL( *iSession, ETrue ); + vfDisplay->SetDisplayRectL( iLocalRect ); + iSetLocalRect = iLocalRect; + } + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::RectChangedL()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::CompleteSessionStructureL( + CMceStreamBundle& /*aLocalBundle*/ ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::CompleteSessionStructureL()" ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + iCameraHandler.SetSession( iSession ); + + // Create outgoing video stream + CMceVideoStream* videoStream = CMceVideoStream::NewLC(); + + CMceRtpSink* rtpsink = CMceRtpSink::NewLC(); + videoStream->AddSinkL( rtpsink ); + CleanupStack::Pop( rtpsink ); + + CMceCameraSource* camera = CMceCameraSource::NewLC( *iManager ); + camera->DisableL(); // Start session in pause mode. + + iCameraHandler.InitializeL( *camera ); + + videoStream->SetSourceL( camera ); + CleanupStack::Pop( camera ); + + // Create incoming video stream + CMceVideoStream* videoInStream = CMceVideoStream::NewL(); + CleanupStack::PushL( videoInStream ); + + MusEngMceUtils::AddDisplayL( *videoInStream, *iManager, Rect() ); + + CMceRtpSource* rtpSource = CMceRtpSource::NewLC( KMusEngJitterBufferLength, + KMusEngJitterBufferTreshold, + KMusEngTwoWayReceivingActivityTimeout ); + videoInStream->SetSourceL( rtpSource ); + CleanupStack::Pop( rtpSource ); + + videoStream->BindL( videoInStream ); + CleanupStack::Pop( videoInStream ); + + iSession->AddStreamL( videoStream ); + CleanupStack::Pop( videoStream ); + + iLiveVideoPlayer->SetMceSession( iSession ); + iRemoteVideoPlayer->SetMceSession( iSession ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::CompleteSessionStructureL()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::CreateMceSessionStructureL( + TBool /*aForceSdpBandwidth*/ ) + { + //Force SDP bandwidth attributes to be included in the INVITE + CMusEngMceOutSession::CreateMceSessionStructureL( ETrue ); + } + +// ----------------------------------------------------------------------------- +// Sets video codec attributes +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::AdjustVideoCodecL( CMceVideoCodec& aVideoCodec, + TMceSourceType aSourceType ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::AdjustVideoCodecL()" ) + + CMusEngLiveSession::AdjustVideoCodecL( aVideoCodec, aSourceType ); + + aVideoCodec.SetKeepAliveTimerL( KMusEngTwoWayRtpKeepAliveTimer ); + if ( aVideoCodec.SdpName() == KMceSDPNameH263() || + aVideoCodec.SdpName() == KMceSDPNameH2632000() ) + { + aVideoCodec.SetKeepAlivePayloadTypeL( KMusEngKeepAlivePayloadTypeVideoH263 ); + } + else if ( aVideoCodec.SdpName() == KMceSDPNameH264() ) + { + aVideoCodec.SetKeepAlivePayloadTypeL( KMusEngKeepAlivePayloadTypeVideoAvc ); + } + else + { + // NOP + } + + aVideoCodec.SetKeepAliveDataL( KNullDesC8() ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::AdjustVideoCodecL()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::AddDisplayL( CMceMediaStream& aStream ) + { + // Vf display is disabled at creation phase if doing bg startup + MusEngMceUtils::AddDisplayL( aStream, + *iManager, + iLocalRect, + IsBackgroundStartup() ); + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::StreamStateChanged( CMceMediaStream& aStream ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::StreamStateChanged()" ) + if ( !iSession ) + { + return; + } + + if ( aStream.Type() == KMceVideo && + aStream.Source() && + aStream.Source()->Type() == KMceRTPSource ) + { + if ( aStream.State() == CMceMediaStream::EStreaming ) + { + ReceivingStarted(); + } + else if ( aStream.State() == CMceMediaStream::EBuffering ) + { + MUS_LOG( "mus: [ENGINE] CMusEngTwoWaySession buffered" ) + + iBuffered = ETrue; + } + else + { + // NOP + } + } + + CMusEngMceSession::StreamStateChanged( aStream ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::StreamStateChanged()" ) + } + +// ----------------------------------------------------------------------------- +// Once inactivity timeout occurs, state change is notified and receiving +// and buffering statuses are cleared. That is safe to do as once receiving +// again continues for real, buffering and streaming events will occur always +// sequentially. If buffering status would not be cleared, some unwanted +// sreaming events would be passed towards client when it disables/enables +// display sink of remote stream while inactivity timer has expired. +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::InactivityTimeout( CMceMediaStream& aStream, + CMceRtpSource& /*aSource*/ ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::InactivityTimeout()" ) + + if ( aStream.Type() == KMceVideo && iReceiving ) + { + iReceiving = EFalse; + iBuffered = EFalse; + if ( iRemoteVideoPlayer ) + { + InformObserverAboutPlayerStateChange( iRemoteVideoPlayer ); + } + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::InactivityTimeout()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::HandleSessionStateChanged( + CMceSession& aSession, + TInt aStatusCode, + const TDesC8& aReasonPhrase ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::HandleSessionStateChanged" ) + + MUS_ENG_LOG_SESSION_STATE_AND_STATUS( aSession, aStatusCode, aReasonPhrase ) + + TBool consumed( EFalse ); + if ( iSession && + iSession == &aSession && + aSession.State() == CMceSession::EEstablished ) + { + CMceVideoStream* stream = NULL; + CMceVideoStream* streamout = NULL; + TRAPD( err, stream = MusEngMceUtils::GetVideoInStreamL( *iSession ) ) + if ( err == KErrNone && stream && stream->IsEnabled() ) + { + TRAP( err, streamout = MusEngMceUtils::GetVideoOutStreamL( *iSession ) ) + if ( err != KErrNone || !streamout || !streamout->IsEnabled() ) + { + MUS_LOG( "mus: [ENGINE] sendrecv downgraded to recvonly, terminate!" ) + consumed = ETrue; + InformObserverAboutSessionFailure( err ); + } + } + } + + if ( !consumed ) + { + CMusEngLiveSession::HandleSessionStateChanged( aSession, + aStatusCode, + aReasonPhrase ); + } + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::HandleSessionStateChanged" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusEngTwoWaySession::CMusEngTwoWaySession() + : CMusEngLiveSession() + { + iSetRemoteRect = TRect( + KMusEngRectNotInit, KMusEngRectNotInit, KMusEngRectNotInit, KMusEngRectNotInit ); + iSetLocalRect = TRect( + KMusEngRectNotInit, KMusEngRectNotInit, KMusEngRectNotInit, KMusEngRectNotInit ); + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::ConstructL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::ConstructL()" ) + + CMusEngLiveSession::ConstructL(); + + iRemoteVideoPlayer = CMusEngRemoteVideoPlayer::NewL( *this, *this ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::ConstructL()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngTwoWaySession::ReceivingStarted() + { + if ( iSession && iBuffered ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWaySession::ReceivingStarted()" ) + + TInt err = MusEngMceUtils::EnableInactivityTimer( + *iSession, KMusEngTwoWayReceivingActivityTimeout ); + + if ( err != KErrNone ) + { + MUS_LOG1("mus: [ENGINE] ReceivingStarted failed %d", err) + InformObserverAboutSessionFailure( err ); + } + else + { + iReceiving = ETrue; + InformObserverAboutPlayerStateChange( iRemoteVideoPlayer ); + InformUiProviderAboutReceivingStart(); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWaySession::ReceivingStarted()" ) + } + } + +// End of file