mmsharing/mmshengine/src/musengtwowaysession.cpp
branchRCL_3
changeset 22 73a1feb507fb
--- /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 <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