--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsharing/mmshengine/src/musengtwowaysession.cpp Fri Jun 11 13:36:18 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 <lcsessionobserver.h>
+#include <mcemanager.h>
+#include <mcecamerasource.h>
+#include <mcevideostream.h>
+#include <mcertpsink.h>
+#include <mcedisplaysink.h>
+#include <mcesession.h>
+#include <mcertpsource.h>
+#include <mcevideocodec.h>
+
+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