mmsharing/livecommsui/lcui/tsrc/ipvtengine/src/musengtwowayrecvsession.cpp
branchRCL_3
changeset 33 bc78a40cd63c
parent 32 73a1feb507fb
child 35 6c57ef9392d2
equal deleted inserted replaced
32:73a1feb507fb 33:bc78a40cd63c
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // USER
       
    20 #include "musengtwowayrecvsession.h"
       
    21 #include "lcsessionobserver.h"
       
    22 #include "musunittesting.h"
       
    23 #include "musengmceutils.h"
       
    24 #include "musenglogger.h"
       
    25 #include "mussipprofilehandler.h"
       
    26 #include "musenglivevideoplayer.h"
       
    27 #include "musengremotevideoplayer.h"
       
    28 
       
    29 // SYSTEM
       
    30 #include <mcemanager.h>
       
    31 #include <mcecamerasource.h>
       
    32 #include <mcevideostream.h>
       
    33 #include <mcertpsink.h>
       
    34 #include <mcedisplaysink.h>
       
    35 #include <mcesession.h>
       
    36 #include <mcertpsource.h>
       
    37 #include <mcestreambundle.h>
       
    38 #include <musmanager.h>
       
    39 
       
    40 const TInt KMusEngJitterBufferLength = 51; //Must be bigger than treshold
       
    41 // Using following value increases treshold buffer to 1 second from 
       
    42 // default 100 ms
       
    43 const TInt KMusEngJitterBufferTreshold = 50;
       
    44 
       
    45 const TUint32 KMusEngTwoWayReceivingActivityTimeout = 5000; // 5 seconds
       
    46 // 6 seconds keepalive timer, needs to be more than receiving timeout
       
    47 const TUint8 KMusEngTwoWayRtpKeepAliveTimer = 6; 
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 //
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 CMusEngTwoWayRecvSession* CMusEngTwoWayRecvSession::NewL()
       
    54     {
       
    55     CMusEngTwoWayRecvSession* self = new( ELeave )CMusEngTwoWayRecvSession();
       
    56     CleanupStack::PushL( self );
       
    57     self->ConstructL();
       
    58     CleanupStack::Pop( self );
       
    59     return self;
       
    60     }
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 CMusEngTwoWayRecvSession::~CMusEngTwoWayRecvSession()
       
    67     {
       
    68     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::~CMusEngTwoWayRecvSession()" )
       
    69     
       
    70     delete iLiveVideoPlayer;  
       
    71     
       
    72     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::~CMusEngTwoWayRecvSession()" )
       
    73     }
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // 
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 void CMusEngTwoWayRecvSession::EnableDisplayL( TBool aEnable )
       
    80     {
       
    81     MUS_LOG1( "mus: [ENGINE]     -> CMusEngTwoWayRecvSession::EnableDisplayL() %d", 
       
    82               aEnable )
       
    83 
       
    84     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
    85 
       
    86     CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
       
    87     MusEngMceUtils::DoEnableDisplayL( *display, aEnable );
       
    88                 
       
    89     CMceDisplaySink* vfDisplay = MusEngMceUtils::GetVfDisplay( *iSession );
       
    90     if ( vfDisplay )
       
    91         {
       
    92         MusEngMceUtils::DoEnableDisplayL( *vfDisplay, aEnable );  
       
    93         }
       
    94         
       
    95     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::EnableDisplayL()")
       
    96     }
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 //
       
   100 // -----------------------------------------------------------------------------
       
   101 //
       
   102 CMusEngMceSession::TDisplayOrientation CMusEngTwoWayRecvSession::OrientationL()
       
   103     {
       
   104     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::RotationL()" )
       
   105     
       
   106     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   107     
       
   108     CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
       
   109     
       
   110     TDisplayOrientation displayOrientation;
       
   111     CMceDisplaySink::TRotation rotation( display->RotationL() );
       
   112     
       
   113     MUS_LOG1( "mus: [ENGINE]     MCE rotation is %d", rotation )
       
   114     
       
   115     if ( rotation == CMceDisplaySink::ENone )
       
   116         {
       
   117         displayOrientation = CMusEngMceSession::EPortrait;
       
   118         }
       
   119     else
       
   120         {
       
   121         displayOrientation = CMusEngMceSession::ELandscape;
       
   122         }
       
   123     
       
   124     MUS_LOG1( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::RotationL() %d", 
       
   125               displayOrientation )
       
   126     
       
   127     return displayOrientation;
       
   128     }
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 //
       
   132 // -----------------------------------------------------------------------------
       
   133 //        
       
   134 void CMusEngTwoWayRecvSession::SetOrientationL( TDisplayOrientation aOrientation )
       
   135     {
       
   136     MUS_LOG1( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::SetOrientationL() %d", 
       
   137               aOrientation )
       
   138               
       
   139     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   140     
       
   141     CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
       
   142             
       
   143     CMceDisplaySink* vfDisplay = MusEngMceUtils::GetVfDisplay( *iSession );
       
   144 
       
   145     CMceDisplaySink::TRotation rotation = ( aOrientation == EPortrait ) ? 
       
   146         CMceDisplaySink::ENone : CMceDisplaySink::EClockwise90Degree;
       
   147     
       
   148     display->SetRotationL( rotation );
       
   149     if ( vfDisplay )
       
   150         {
       
   151         vfDisplay->SetRotationL( rotation );
       
   152         }
       
   153     
       
   154     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::SetOrientationL()" )
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 void CMusEngTwoWayRecvSession::SetRectsL( 
       
   162     const TRect& aRemoteRect,
       
   163     const TRect& aLocalRect )
       
   164     {
       
   165     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::SetRectsL()" )  
       
   166      
       
   167     iLocalRect = aLocalRect;
       
   168     iRect = aRemoteRect;
       
   169     RectChangedL();
       
   170     
       
   171     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::SetRectsL()" )
       
   172     }
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 void CMusEngTwoWayRecvSession::SetSecondaryRectL( const TRect& aSecondaryRect )
       
   179     {
       
   180     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::SetSecondaryRectL()" )
       
   181     
       
   182     iLocalRect = aSecondaryRect;
       
   183     RectChangedL();
       
   184 
       
   185     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::SetSecondaryRectL()" )
       
   186     }
       
   187 
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 TRect CMusEngTwoWayRecvSession::SecondaryRect() const
       
   193     {
       
   194     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::SecondaryRect()" )
       
   195     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::SecondaryRect()" )
       
   196     return iLocalRect;
       
   197     }
       
   198 
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 // -----------------------------------------------------------------------------
       
   202 //
       
   203 TMusEngCameraHandler& CMusEngTwoWayRecvSession::Camera()
       
   204     {
       
   205     return iCameraHandler;
       
   206     }
       
   207 
       
   208 // -----------------------------------------------------------------------------
       
   209 // From MLcSession
       
   210 // -----------------------------------------------------------------------------
       
   211 //
       
   212 MLcVideoPlayer* CMusEngTwoWayRecvSession::LocalVideoPlayer()
       
   213     {
       
   214     return iLiveVideoPlayer;
       
   215     }
       
   216 
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 // -----------------------------------------------------------------------------
       
   220 //
       
   221 
       
   222 void CMusEngTwoWayRecvSession::RectChangedL()
       
   223     {
       
   224     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::RectChangedL()" )
       
   225 
       
   226 
       
   227     // If session is not yet created, do nothing
       
   228     if ( iSession && iSession->State() != CMceSession::ETerminated )
       
   229         {
       
   230         TRect remoteRect( Rect() );
       
   231         MUS_LOG2( "mus: [ENGINE]  remote tl.ix=%d tl.iy=%d", 
       
   232                   remoteRect.iTl.iX, remoteRect.iTl.iY )
       
   233         MUS_LOG2( "mus: [ENGINE]  remote brc%d br.iy=%d", 
       
   234                   remoteRect.iBr.iX, remoteRect.iBr.iY )    
       
   235         MUS_LOG2( "mus: [ENGINE]  local tl.ix=%d tl.iy=%d", 
       
   236                   iLocalRect.iTl.iX, iLocalRect.iTl.iY )
       
   237         MUS_LOG2( "mus: [ENGINE]  local br.ix=%d br.iy=%d", 
       
   238                   iLocalRect.iBr.iX, iLocalRect.iBr.iY )
       
   239         
       
   240         if ( remoteRect != iSetRemoteRect )
       
   241             {
       
   242             CMceDisplaySink* display = MusEngMceUtils::GetReceivingDisplayL( *iSession );
       
   243             display->SetDisplayRectL( remoteRect );
       
   244             iSetRemoteRect = remoteRect;
       
   245             }
       
   246         
       
   247         if ( iLocalRect != iSetLocalRect )
       
   248             {
       
   249             CMceDisplaySink* vfDisplay = MusEngMceUtils::GetVfDisplay( *iSession );
       
   250             if ( vfDisplay )
       
   251                 {
       
   252                 vfDisplay->SetDisplayRectL( iLocalRect );
       
   253                 }
       
   254             iSetLocalRect = iLocalRect;
       
   255             }
       
   256         }
       
   257 
       
   258     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::RectChangedL()" )
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 void CMusEngTwoWayRecvSession::CompleteSessionStructureL()
       
   266     {
       
   267     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::CompleteSessionStructureL()" )
       
   268 
       
   269     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   270     
       
   271     iCameraHandler.SetSession( iSession );
       
   272     
       
   273     // Force bandwidth line usage in sdp as it is mandatory
       
   274     // at MT side based on GSMA VS specification IR.74. Bandwidth is set to
       
   275     // session or to media level based on sender's way of usage. If other end
       
   276     // is not using bandwidth attribute at all, media level is preferred.
       
   277     SetSessionSdpLinesL( *iSession, ETrue );
       
   278 
       
   279     CMceStreamBundle* localBundle =
       
   280                               CMceStreamBundle::NewLC( CMceStreamBundle::ELS );
       
   281 
       
   282     const RPointerArray<CMceMediaStream>& streams = iSession->Streams();
       
   283     
       
   284     CMceMediaStream* videoInStream = NULL;
       
   285     CMceMediaStream* videoOutStream = NULL;
       
   286     
       
   287     // Search interesting video streams, sendrecv is preferred
       
   288     TBool sendRecvVideoFound( EFalse );
       
   289     for( TInt i = 0; i < streams.Count(); ++i )
       
   290         {
       
   291         if ( MusEngMceUtils::IsVideoInStream( *streams[i] ) &&
       
   292              !sendRecvVideoFound )
       
   293             {
       
   294             videoInStream = streams[i];
       
   295             
       
   296             if ( streams[i]->BoundStream() )
       
   297                 {
       
   298                 videoOutStream = &streams[i]->BoundStreamL();
       
   299                 }
       
   300             }
       
   301         else if ( streams[i]->BoundStream() &&
       
   302                   MusEngMceUtils::IsVideoInStream( streams[i]->BoundStreamL() ) &&
       
   303                   !sendRecvVideoFound )
       
   304             {
       
   305             videoInStream = &streams[i]->BoundStreamL();
       
   306                 
       
   307             videoOutStream = streams[i];
       
   308             }
       
   309         else
       
   310             {
       
   311             // NOP
       
   312             }
       
   313         
       
   314         sendRecvVideoFound = ( videoInStream && videoOutStream );
       
   315         }
       
   316     
       
   317     CompleteSessionStructureAudioPartL( streams, *localBundle, videoInStream, videoOutStream );
       
   318     
       
   319     if ( videoInStream )
       
   320         {
       
   321         CompleteSessionStructureInStreamL( *videoInStream, *localBundle );
       
   322         }
       
   323     else
       
   324         {
       
   325         // At least receiving video stream is required
       
   326         User::Leave( KErrCorrupt );
       
   327         }
       
   328     
       
   329     if ( videoOutStream )
       
   330         {
       
   331         CompleteSessionStructureOutStreamL( *videoOutStream );
       
   332         }
       
   333     
       
   334     // Destroy bundle if it is not needed or transfer ownership
       
   335     if ( localBundle->Streams().Count() > 1 )
       
   336         {
       
   337         iSession->AddBundleL( localBundle );
       
   338         CleanupStack::Pop( localBundle );
       
   339         }
       
   340     else
       
   341         {
       
   342         CleanupStack::PopAndDestroy( localBundle );
       
   343         }
       
   344     
       
   345     AdjustStreamsAndCodecsL();
       
   346     
       
   347     iSession->UpdateL();
       
   348     
       
   349     // Now session state is right to adjust volume
       
   350     SetSpeakerVolumeL( LcVolumeL() );
       
   351     
       
   352     iSipProfileHandler->CreateProfileL( iSession->Profile() );
       
   353     
       
   354     iRemoteVideoPlayer->SetMceSession( iSession );
       
   355 
       
   356     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::CompleteSessionStructureL()" )
       
   357     }
       
   358 
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 // -----------------------------------------------------------------------------
       
   362 //
       
   363 CMusEngTwoWayRecvSession::CMusEngTwoWayRecvSession() 
       
   364     : CMusEngReceiveSession()
       
   365     {
       
   366     iMceManagerUid.iUid = CMusManager::ESipInviteDesired2WayVideo;
       
   367     }
       
   368 
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 // -----------------------------------------------------------------------------
       
   372 //
       
   373 void CMusEngTwoWayRecvSession::ConstructL()
       
   374     {
       
   375     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::ConstructL()" )
       
   376     
       
   377     iCameraHandler.ReadCameraUsageKeyL();
       
   378     CMusEngReceiveSession::ConstructL();
       
   379     
       
   380     iLiveVideoPlayer = 
       
   381         CMusEngLiveVideoPlayer::NewL( *this, iCameraHandler, *this );
       
   382     
       
   383     // Override receiving timeout and keepalive values of
       
   384     // normal one-way receiving session
       
   385     //
       
   386     iReceivingInactivityTimeout = KMusEngTwoWayReceivingActivityTimeout; 
       
   387     iKeepaliveTimer = KMusEngTwoWayRtpKeepAliveTimer;
       
   388 
       
   389     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::ConstructL()" )
       
   390     }
       
   391 
       
   392 // -----------------------------------------------------------------------------
       
   393 // When checking audio streams also not interesting streams are removed from
       
   394 // session. Stream if removed if one of following apply:
       
   395 // 1. Is not and does not contain incoming video or audio
       
   396 // 2. We already have one incoming video stream
       
   397 // 3. Stream is audio and we run operator variant where audio is 
       
   398 //    not allowed.
       
   399 // 4. Two-way video exists and this one is audio
       
   400 // -----------------------------------------------------------------------------
       
   401 //
       
   402 void CMusEngTwoWayRecvSession::CompleteSessionStructureAudioPartL( 
       
   403     const RPointerArray<CMceMediaStream>& aStreams, 
       
   404     CMceStreamBundle& aLocalBundle, 
       
   405     CMceMediaStream* aVideoInStream,
       
   406     CMceMediaStream* aVideoOutStream )
       
   407     {
       
   408     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::CompleteSessionStructureAudioPartL()" )
       
   409     
       
   410     // Audio streams not allowed in two-way session or in operator variant
       
   411     TBool audioAllowed(  !( aVideoInStream && aVideoOutStream ) && !iOperatorVariant );
       
   412     
       
   413     for( TInt i = 0; i < aStreams.Count(); ++i )
       
   414         {
       
   415         // Audio supported currently only in recvonly case
       
   416         if ( audioAllowed &&
       
   417              MusEngMceUtils::IsAudioInStream( *aStreams[i] ) )
       
   418             {
       
   419             MusEngMceUtils::AddSpeakerL( *aStreams[i] );
       
   420             
       
   421             aLocalBundle.AddStreamL( *aStreams[i] );
       
   422             
       
   423             // Disable possible opposite stream to indicate that sendrecv audio is
       
   424             // not allowed.
       
   425             if ( aStreams[i]->BoundStream() )
       
   426                 {
       
   427                 MusEngMceUtils::DisableStreamL( aStreams[i]->BoundStreamL() );
       
   428                 }
       
   429             }
       
   430         else if ( audioAllowed &&
       
   431                   aStreams[i]->BoundStream() &&
       
   432                   MusEngMceUtils::IsAudioInStream( aStreams[i]->BoundStreamL() ) )
       
   433             {
       
   434             MusEngMceUtils::AddSpeakerL( aStreams[i]->BoundStreamL() );
       
   435     
       
   436             aLocalBundle.AddStreamL( aStreams[i]->BoundStreamL() );
       
   437             
       
   438             // Disable opposite stream to indicate that sendrecv audio is not allowed.
       
   439             MusEngMceUtils::DisableStreamL( *aStreams[i] );
       
   440             }
       
   441         else if ( aStreams[ i ] != aVideoInStream && aStreams[ i ] != aVideoOutStream )
       
   442             {
       
   443            iSession->RemoveStreamL( *aStreams[i] );
       
   444         
       
   445             // Since succesfull removal of a stream has decreased the amount
       
   446             // of streams in array by one, we have to modify the index
       
   447             --i;
       
   448             }
       
   449         else
       
   450             {
       
   451             // NOP
       
   452             }
       
   453         }
       
   454     
       
   455     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::CompleteSessionStructureAudioPartL()" )
       
   456     }
       
   457 
       
   458 // -----------------------------------------------------------------------------
       
   459 //
       
   460 // -----------------------------------------------------------------------------
       
   461 //
       
   462 void CMusEngTwoWayRecvSession::CompleteSessionStructureInStreamL( 
       
   463     CMceMediaStream& aVideoInStream, CMceStreamBundle& aLocalBundle )
       
   464     {
       
   465     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::CompleteSessionStructureInStreamL()" )
       
   466     
       
   467     SetMediaSdpLinesL( aVideoInStream, ETrue );
       
   468 
       
   469     MusEngMceUtils::AddDisplayL( aVideoInStream, *iManager, Rect() );
       
   470     
       
   471     static_cast<CMceRtpSource*>(aVideoInStream.Source())->UpdateL( 
       
   472                                            KMusEngJitterBufferLength,
       
   473                                            KMusEngJitterBufferTreshold,
       
   474                                            KMusEngTwoWayReceivingActivityTimeout );
       
   475                                             
       
   476     aLocalBundle.AddStreamL( aVideoInStream );
       
   477     
       
   478     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::CompleteSessionStructureInStreamL()" )
       
   479     }
       
   480 
       
   481 // -----------------------------------------------------------------------------
       
   482 //
       
   483 // -----------------------------------------------------------------------------
       
   484 //
       
   485 void CMusEngTwoWayRecvSession::CompleteSessionStructureOutStreamL( 
       
   486     CMceMediaStream& aVideoOutStream )
       
   487     {
       
   488     MUS_LOG( "mus: [ENGINE]  -> CMusEngTwoWayRecvSession::CompleteSessionStructureOutStreamL()" )
       
   489     
       
   490     SetMediaSdpLinesL( aVideoOutStream, ETrue );
       
   491         
       
   492     CMceCameraSource* camera = NULL;
       
   493     TRAP_IGNORE( camera = MusEngMceUtils::GetCameraL( *iSession ) )
       
   494     if ( !camera )
       
   495         {
       
   496         camera = CMceCameraSource::NewLC( *iManager );
       
   497         aVideoOutStream.SetSourceL( camera );
       
   498         CleanupStack::Pop( camera );
       
   499         }
       
   500        
       
   501     camera->DisableL(); // Start session in pause mode.
       
   502     
       
   503     iCameraHandler.InitializeL( *camera );
       
   504     
       
   505     CMceVideoStream* vfStream = CMceVideoStream::NewLC();
       
   506 
       
   507     vfStream->SetSourceL( aVideoOutStream.Source() );
       
   508          
       
   509     // Complete stream
       
   510     MusEngMceUtils::AddDisplayL( *vfStream, *iManager, SecondaryRect() );
       
   511     
       
   512     iSession->AddStreamL( vfStream );
       
   513     CleanupStack::Pop( vfStream );
       
   514     
       
   515     iLiveVideoPlayer->SetMceSession( iSession );
       
   516     
       
   517     MUS_LOG( "mus: [ENGINE]  <- CMusEngTwoWayRecvSession::CompleteSessionStructureOutStreamL()" )
       
   518     }
       
   519 
       
   520 
       
   521 // End of file