--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tsrc/musenginestub/src/musengtwowayrecvsession.cpp Tue Aug 31 15:12:07 2010 +0300
@@ -0,0 +1,540 @@
+/*
+* 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 "musengtwowayrecvsession.h"
+#include "musengsessionobserver.h"
+#include "musengreceivesessionobserver.h"
+#include "musunittesting.h"
+#include "musengmceutils.h"
+#include "musenglogger.h"
+#include "mussipprofilehandler.h"
+
+// SYSTEM
+#include <mcemanager.h>
+#include <mcecamerasource.h>
+#include <mcevideostream.h>
+#include <mcertpsink.h>
+#include <mcedisplaysink.h>
+#include <mcesession.h>
+#include <mcertpsource.h>
+#include <mcestreambundle.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;
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CMusEngTwoWayRecvSession* CMusEngTwoWayRecvSession::NewL(
+ const TRect& aRemoteRect,
+ const TRect& aLocalRect,
+ MMusEngSessionObserver& aSessionObserver,
+ MMusEngReceiveSessionObserver& aReceiveSessionObserver )
+ {
+ CMusEngTwoWayRecvSession* self = new( ELeave ) CMusEngTwoWayRecvSession(
+ aSessionObserver,
+ aReceiveSessionObserver,
+ aRemoteRect,
+ aLocalRect );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMusEngTwoWayRecvSession::~CMusEngTwoWayRecvSession()
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::~CMusEngTwoWayRecvSession()" )
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::~CMusEngTwoWayRecvSession()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::EnableDisplayL( TBool aEnable )
+ {
+ MUS_LOG1( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::EnableDisplayL() %d",
+ aEnable )
+
+ __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
+
+ CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
+ MusEngMceUtils::DoEnableDisplayL( *display, aEnable );
+
+ CMceDisplaySink* vfDisplay = MusEngMceUtils::GetVfDisplay( *iSession );
+ if ( vfDisplay )
+ {
+ MusEngMceUtils::DoEnableDisplayL( *vfDisplay, aEnable );
+ }
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::EnableDisplayL()")
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMusEngMceSession::TDisplayOrientation CMusEngTwoWayRecvSession::OrientationL()
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::RotationL()" )
+
+ __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
+
+ CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
+
+ TDisplayOrientation displayOrientation;
+ CMceDisplaySink::TRotation rotation( display->RotationL() );
+
+ MUS_LOG1( "mus: [ENGINE] MCE rotation is %d", rotation )
+
+ if ( rotation == CMceDisplaySink::ENone )
+ {
+ displayOrientation = CMusEngMceSession::EPortrait;
+ }
+ else
+ {
+ displayOrientation = CMusEngMceSession::ELandscape;
+ }
+
+ MUS_LOG1( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::RotationL() %d",
+ displayOrientation )
+
+ return displayOrientation;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::SetOrientationL( TDisplayOrientation aOrientation )
+ {
+ MUS_LOG1( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::SetOrientationL() %d",
+ aOrientation )
+
+ __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
+
+ CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
+
+ CMceDisplaySink* vfDisplay = MusEngMceUtils::GetVfDisplay( *iSession );
+
+ CMceDisplaySink::TRotation rotation = ( aOrientation == EPortrait ) ?
+ CMceDisplaySink::ENone : CMceDisplaySink::EClockwise90Degree;
+
+ display->SetRotationL( rotation );
+ if ( vfDisplay )
+ {
+ vfDisplay->SetRotationL( rotation );
+ }
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::SetOrientationL()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMusEngTwoWayRecvSession::SetRectsL(
+ const TRect& aRemoteRect,
+ const TRect& aLocalRect )
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::SetRectsL()" )
+
+ iLocalRect = aLocalRect;
+ iRect = aRemoteRect;
+ RectChangedL();
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::SetRectsL()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMusEngTwoWayRecvSession::SetLocalRectL( const TRect& aLocalRect )
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::SetLocalRectL()" )
+
+ iLocalRect = aLocalRect;
+ RectChangedL();
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::SetLocalRectL()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TRect CMusEngTwoWayRecvSession::LocalRect() const
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::LocalRect()" )
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::LocalRect()" )
+ return iLocalRect;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TMusEngCameraHandler& CMusEngTwoWayRecvSession::Camera()
+ {
+ return iCameraHandler;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+
+void CMusEngTwoWayRecvSession::RectChangedL()
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::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 brc%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 )
+
+ CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
+ display->SetDisplayRectL( remoteRect );
+
+ CMceDisplaySink* vfDisplay = MusEngMceUtils::GetVfDisplay( *iSession );
+ if ( vfDisplay )
+ {
+ vfDisplay->SetDisplayRectL( iLocalRect );
+ }
+ }
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::RectChangedL()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::CompleteSessionStructureL()
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::CompleteSessionStructureL()" )
+
+ __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
+
+ iCameraHandler.SetSession( iSession );
+
+ // Force bandwidth line usage in sdp as it is mandatory
+ // at MT side based on GSMA VS specification IR.74. Bandwidth is set to
+ // session or to media level based on sender's way of usage. If other end
+ // is not using bandwidth attribute at all, media level is preferred.
+ SetSessionSdpLinesL( *iSession, ETrue );
+
+ CMceStreamBundle* localBundle =
+ CMceStreamBundle::NewLC( CMceStreamBundle::ELS );
+
+ const RPointerArray<CMceMediaStream>& streams = iSession->Streams();
+
+ CMceMediaStream* videoInStream = NULL;
+ CMceMediaStream* videoOutStream = NULL;
+
+ // Search interesting video streams, sendrecv is preferred
+ TBool sendRecvVideoFound( EFalse );
+ for( TInt i = 0; i < streams.Count(); ++i )
+ {
+ if ( MusEngMceUtils::IsVideoInStream( *streams[i] ) &&
+ !sendRecvVideoFound )
+ {
+ videoInStream = streams[i];
+
+ if ( streams[i]->BoundStream() )
+ {
+ videoOutStream = &streams[i]->BoundStreamL();
+ }
+ }
+ else if ( streams[i]->BoundStream() &&
+ MusEngMceUtils::IsVideoInStream( streams[i]->BoundStreamL() ) &&
+ !sendRecvVideoFound )
+ {
+ videoInStream = &streams[i]->BoundStreamL();
+
+ videoOutStream = streams[i];
+ }
+ else
+ {
+ // NOP
+ }
+
+ sendRecvVideoFound = ( videoInStream && videoOutStream );
+ }
+
+ CompleteSessionStructureAudioPartL( streams, *localBundle, videoInStream, videoOutStream );
+
+ if ( videoInStream )
+ {
+ CompleteSessionStructureInStreamL( *videoInStream, *localBundle );
+ }
+ else
+ {
+ // At least receiving video stream is required
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( videoOutStream )
+ {
+ CompleteSessionStructureOutStreamL( *videoOutStream );
+ }
+
+ // Destroy bundle if it is not needed or transfer ownership
+ if ( localBundle->Streams().Count() > 1 )
+ {
+ iSession->AddBundleL( localBundle );
+ CleanupStack::Pop( localBundle );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( localBundle );
+ }
+
+ AdjustStreamsAndCodecsL();
+
+ iSession->UpdateL();
+
+ // Now session state is right to adjust volume
+ SetSpeakerVolumeL( VolumeL() );
+
+ iSipProfileHandler->CreateProfileL( iSession->Profile() );
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::CompleteSessionStructureL()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::StreamStateChanged( CMceMediaStream& aStream,
+ CMceMediaSink& aSink )
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::StreamStateChanged( sink )" )
+ if ( !iSession )
+ {
+ return;
+ }
+
+ MUS_ENG_LOG_STREAM_STATE( aStream )
+
+ // TODO: if display sink buffers, inform ui with some callback
+ // so that it can modify display rects accordingly
+
+ CMusEngMceSession::StreamStateChanged( aStream, aSink );
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::StreamStateChanged( sink )" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::StreamStateChanged( CMceMediaStream& aStream )
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::StreamStateChanged()" )
+ if ( !iSession )
+ {
+ return;
+ }
+
+ MUS_ENG_LOG_STREAM_STATE( aStream )
+
+ // TODO: if receiving video stream buffers, inform ui with some callback
+ // so that it can modify display rects accordingly
+
+ CMusEngReceiveSession::StreamStateChanged( aStream );
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::StreamStateChanged()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMusEngTwoWayRecvSession::CMusEngTwoWayRecvSession(
+ MMusEngSessionObserver& aSessionObserver,
+ MMusEngReceiveSessionObserver& aReceiveSessionObserver,
+ const TRect& aRemoteRect,
+ const TRect& aLocalRect ) :
+ CMusEngReceiveSession( aSessionObserver,
+ aReceiveSessionObserver,
+ aRemoteRect ),
+ iLocalRect( aLocalRect )
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::ConstructL()
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::ConstructL()" )
+
+ iCameraHandler.ReadCameraUsageKeyL();
+ CMusEngReceiveSession::ConstructL();
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::ConstructL()" )
+ }
+
+// -----------------------------------------------------------------------------
+// When checking audio streams also not interesting streams are removed from
+// session. Stream if removed if one of following apply:
+// 1. Is not and does not contain incoming video or audio
+// 2. We already have one incoming video stream
+// 3. Stream is audio and we run operator variant where audio is
+// not allowed.
+// 4. Two-way video exists and this one is audio
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::CompleteSessionStructureAudioPartL(
+ const RPointerArray<CMceMediaStream>& aStreams,
+ CMceStreamBundle& aLocalBundle,
+ CMceMediaStream* aVideoInStream,
+ CMceMediaStream* aVideoOutStream )
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::CompleteSessionStructureAudioPartL()" )
+
+ // Audio streams not allowed in two-way session or in operator variant
+ TBool audioAllowed( !( aVideoInStream && aVideoOutStream ) && !iOperatorVariant );
+
+ for( TInt i = 0; i < aStreams.Count(); ++i )
+ {
+ // Audio supported currently only in recvonly case
+ if ( audioAllowed &&
+ MusEngMceUtils::IsAudioInStream( *aStreams[i] ) )
+ {
+ MusEngMceUtils::AddSpeakerL( *aStreams[i] );
+
+ aLocalBundle.AddStreamL( *aStreams[i] );
+
+ // Disable possible opposite stream to indicate that sendrecv audio is
+ // not allowed.
+ if ( aStreams[i]->BoundStream() )
+ {
+ MusEngMceUtils::DisableStreamL( aStreams[i]->BoundStreamL() );
+ }
+ }
+ else if ( audioAllowed &&
+ aStreams[i]->BoundStream() &&
+ MusEngMceUtils::IsAudioInStream( aStreams[i]->BoundStreamL() ) )
+ {
+ MusEngMceUtils::AddSpeakerL( aStreams[i]->BoundStreamL() );
+
+ aLocalBundle.AddStreamL( aStreams[i]->BoundStreamL() );
+
+ // Disable opposite stream to indicate that sendrecv audio is not allowed.
+ MusEngMceUtils::DisableStreamL( *aStreams[i] );
+ }
+ else if ( aStreams[ i ] != aVideoInStream && aStreams[ i ] != aVideoOutStream )
+ {
+ iSession->RemoveStreamL( *aStreams[i] );
+
+ // Since succesfull removal of a stream has decreased the amount
+ // of streams in array by one, we have to modify the index
+ --i;
+ }
+ else
+ {
+ // NOP
+ }
+ }
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::CompleteSessionStructureAudioPartL()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::CompleteSessionStructureInStreamL(
+ CMceMediaStream& aVideoInStream, CMceStreamBundle& aLocalBundle )
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::CompleteSessionStructureInStreamL()" )
+
+ SetMediaSdpLinesL( aVideoInStream, ETrue );
+
+ MusEngMceUtils::AddDisplayL( aVideoInStream, *iManager, Rect() );
+
+ static_cast<CMceRtpSource*>(aVideoInStream.Source())->UpdateL(
+ KMusEngJitterBufferLength,
+ KMusEngJitterBufferTreshold );
+
+ aLocalBundle.AddStreamL( aVideoInStream );
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::CompleteSessionStructureInStreamL()" )
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTwoWayRecvSession::CompleteSessionStructureOutStreamL(
+ CMceMediaStream& aVideoOutStream )
+ {
+ MUS_LOG( "mus: [ENGINE] -> CMusEngTwoWayRecvSession::CompleteSessionStructureOutStreamL()" )
+
+ SetMediaSdpLinesL( aVideoOutStream, ETrue );
+
+ CMceCameraSource* camera = NULL;
+ TRAP_IGNORE( camera = MusEngMceUtils::GetCameraL( *iSession ) )
+ if ( !camera )
+ {
+ camera = CMceCameraSource::NewLC( *iManager );
+ aVideoOutStream.SetSourceL( camera );
+ CleanupStack::Pop( camera );
+ }
+
+ camera->DisableL(); // Start session in pause mode.
+
+ iCameraHandler.InitializeL( *camera );
+
+ CMceVideoStream* vfStream = CMceVideoStream::NewLC();
+
+ vfStream->SetSourceL( aVideoOutStream.Source() );
+
+ // Complete stream
+ MusEngMceUtils::AddDisplayL( *vfStream, *iManager, LocalRect() );
+
+ iSession->AddStreamL( vfStream );
+ CleanupStack::Pop( vfStream );
+
+ MUS_LOG( "mus: [ENGINE] <- CMusEngTwoWayRecvSession::CompleteSessionStructureOutStreamL()" )
+ }
+
+// End of file