multimediacommscontroller/mmccrtpsourcesink/src/mccrtpdatasink.cpp
changeset 0 1bce908db942
child 18 817c922b90eb
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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:    RTP Datasink
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <mmf/common/mmfcontroller.h> 
       
    23 
       
    24 #include "rtpheader.h"
       
    25 #include <srtpcryptocontext.h>
       
    26 #include <srtpstreamout.h>
       
    27 
       
    28 #include "mccrtpdatasink.h"
       
    29 #include "mmccevents.h"
       
    30 #include "mccinternaldef.h"
       
    31 #include "mccrtpdefs.h"
       
    32 #include "mmccinterfacedef.h"
       
    33 #include "mccrtpmediaclock.h"
       
    34 
       
    35 // MACROS
       
    36 
       
    37 // EXTERNAL DATA STRUCTURES
       
    38 
       
    39 // EXTERNAL FUNCTION PROTOTYPES  
       
    40 
       
    41 // CONSTANTS
       
    42 
       
    43 // MACROS
       
    44 #define MCC_RTPSINK_ENDPOINT_ID MCC_ENDPOINT_ID( static_cast<MDataSink*>( this ) )
       
    45 
       
    46 // LOCAL CONSTANTS AND MACROS
       
    47 
       
    48 // MODULE DATA STRUCTURES
       
    49 
       
    50 // LOCAL FUNCTION PROTOTYPES
       
    51 
       
    52 // FORWARD DECLARATIONS
       
    53 
       
    54 // ============================= LOCAL FUNCTIONS ===============================
       
    55 
       
    56 // ============================ MEMBER FUNCTIONS ===============================
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // CMccRtpDataSink::CMccRtpDataSink
       
    60 // C++ default constructor can NOT contain any code, that
       
    61 // might leave.
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 CMccRtpDataSink::CMccRtpDataSink() :
       
    65     CMccDataSink( KMccRtpSinkUid ),
       
    66     MMccRtpInterface(), iRtpStreamId( KNullId )
       
    67     {
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CMccRtpDataSink::NewSinkL
       
    72 // Static constructor.
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 MDataSink* CMccRtpDataSink::NewSinkL( TUid /*aImplementationUid*/, 
       
    76                                       const TDesC8& /*aInitData*/ )
       
    77     {
       
    78     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::NewSinkL()" )
       
    79        
       
    80     CMccRtpDataSink* self = new ( ELeave ) CMccRtpDataSink();
       
    81     return static_cast<MDataSink*>( self ); 
       
    82     }
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CMccRtpDataSink::ConstructSinkL
       
    86 // class MDataSink inherited 2nd phase construction
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 void CMccRtpDataSink::ConstructSinkL( const TDesC8& aInitData )
       
    90     {
       
    91     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::ConstructSinkL" )
       
    92     
       
    93     SetStateL( ERtpStateConstructed );
       
    94     
       
    95     TInt res = aInitData.Compare( KNullDesC8 );
       
    96     if ( 0 != res )
       
    97         {
       
    98         TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSink::ConstructSinkL KErrArgument" )
       
    99     
       
   100         User::Leave( KErrArgument );
       
   101         }
       
   102         
       
   103     #ifdef FTD_ENABLED
       
   104     TInt err = iStreamStatsQueue.OpenGlobal( KMccStreamStats, EOwnerProcess );
       
   105     if ( KErrNone != err )
       
   106         {
       
   107         User::Leave( err );
       
   108         }
       
   109     #endif
       
   110     }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CMccRtpDataSink::~CMccRtpDataSink
       
   114 // Destructor
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 CMccRtpDataSink::~CMccRtpDataSink()
       
   118     {
       
   119     TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::~CMccRtpDataSink 0x%x", this )
       
   120     
       
   121     // We don't own this
       
   122     iEventHandler = NULL;
       
   123         
       
   124     CloseStreams();
       
   125         
       
   126     iDataSource = NULL;
       
   127     iBufferToBeEmptied = NULL;
       
   128     
       
   129     iUsers.Close();
       
   130         
       
   131     delete iSender;
       
   132     
       
   133     #ifdef FTD_ENABLED
       
   134     iStreamStatsQueue.Close();
       
   135     #endif
       
   136     }
       
   137 
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CMccRtpDataSink::SetCurrentUser
       
   141 // -----------------------------------------------------------------------------
       
   142 //
       
   143 void CMccRtpDataSink::SetCurrentUser( MAsyncEventHandler* aEventHandler )
       
   144     {
       
   145     iEventHandler = aEventHandler;
       
   146     }
       
   147 
       
   148 
       
   149 // -----------------------------------------------------------------------------
       
   150 // CMccRtpDataSink::Mute
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 void CMccRtpDataSink::Mute( TBool aMuteOn, TUint8 aExceptionPt )
       
   154     {
       
   155     TRACE_RTP_SINK_PRINT3( "CMccRtpDataSink::Mute, ENABLED: %d, PT: %u", 
       
   156         aMuteOn, aExceptionPt )
       
   157     
       
   158     iMuteOn = aMuteOn;
       
   159     iExceptionPt = aExceptionPt;
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CMccRtpDataSink::SinkThreadLogon
       
   164 //
       
   165 // Method to 'logon' the data sink to the same thread that sink will be consuming
       
   166 // data in. Thread specific initialisation is done here.
       
   167 // -----------------------------------------------------------------------------
       
   168 //
       
   169 TInt CMccRtpDataSink::SinkThreadLogon( MAsyncEventHandler& aEventHandler ) 
       
   170     {
       
   171     TRACE_RTP_SINK_PRINT ( "CMccRtpDataSink::SinkThreadLogon" )
       
   172     
       
   173     if ( FindRtpUserEntryForCurrent( aEventHandler ) )
       
   174         {
       
   175         TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::SinkThreadLogon, ERR: %d", KErrAlreadyExists )
       
   176         return KErrAlreadyExists;
       
   177         }
       
   178 
       
   179     TMccRtpUser user( &aEventHandler );
       
   180     TInt err = iUsers.Append( user );
       
   181     
       
   182     TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::SinkThreadLogon, exit with err: %d", err )
       
   183     
       
   184     return err;
       
   185     }
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CMccRtpDataSink::SinkThreadLogoff
       
   189 //
       
   190 // Method to 'logoff' the data sink from the same thread that sink consumes 
       
   191 // data in. Thread specific releasing of resources is done here.
       
   192 // -----------------------------------------------------------------------------
       
   193 //
       
   194 void CMccRtpDataSink::SinkThreadLogoff() 
       
   195     {
       
   196     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SinkThreadLogoff" )
       
   197     
       
   198     RemoveCurrentRtpUser();
       
   199     
       
   200     SetCurrentUser( NULL );
       
   201     
       
   202     if ( 0 == iUsers.Count() )
       
   203         {
       
   204         // SinkThreadLogoff may be called while not stopped, so don't
       
   205         // bother checking any states here. SinkThreadLogoff means that the
       
   206         // thread is going down, so we must cleanup here...
       
   207     
       
   208         StopKeepalive();
       
   209     	CloseStreams();
       
   210         iRtpAPI = NULL;
       
   211         iRtpStreamId = KNullId;
       
   212         iUsers.Close();
       
   213         
       
   214     	delete iSender;
       
   215 	    iSender = NULL;
       
   216         }
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CMccRtpDataSink::SetSinkDataTypeCode
       
   221 // Sets the datatype code ( codec )
       
   222 // ----------------------------------------------------------------------------- 
       
   223 //
       
   224 TInt CMccRtpDataSink::SetSinkDataTypeCode( TFourCC aCodec, TMediaId aMedia )
       
   225     {
       
   226     if ( KUidMediaTypeAudio == aMedia.iMediaType || 
       
   227          KUidMediaTypeVideo == aMedia.iMediaType )
       
   228         {
       
   229         TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::SetSinkDataTypeCode, mediatype:%d", 
       
   230                                aMedia.iMediaType.iUid )
       
   231         iMedia = aMedia;
       
   232         iCodecInfo.iFourCC = aCodec;
       
   233         return KErrNone;
       
   234         }
       
   235     else
       
   236         {
       
   237         return KErrNotSupported;
       
   238         }
       
   239     }
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // CMccRtpDataSink::SinkDataTypeCode
       
   243 // Returns the datatype code ( codec )
       
   244 // -----------------------------------------------------------------------------
       
   245 //
       
   246 TFourCC CMccRtpDataSink::SinkDataTypeCode( TMediaId aMediaId )
       
   247     {
       
   248     if ( KUidMediaTypeAudio == aMediaId.iMediaType ||
       
   249          KUidMediaTypeVideo == aMediaId.iMediaType )
       
   250         {
       
   251         return iCodecInfo.iFourCC;
       
   252         }
       
   253     else
       
   254         {
       
   255         // Initializes to KMMFFourCCCodeNULL so the caller cannot see
       
   256         // if this sink really has some media type currently registered
       
   257         return TFourCC();
       
   258         }
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 // CMccRtpDataSink::EmptyBufferL
       
   263 // NOT SUPPORTED. MDataSink pure virtual function must be implemented.
       
   264 // -----------------------------------------------------------------------------
       
   265 //
       
   266 void CMccRtpDataSink::EmptyBufferL( CMMFBuffer* /*aBuffer*/, 
       
   267                                     MDataSource* /*aSupplier*/, 
       
   268                                     TMediaId /*aMediaId*/ )
       
   269     {
       
   270     User::Leave( KErrNotSupported );
       
   271     }
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // CMccRtpDataSink::EmptyBufferL
       
   275 // Overload to class MDataSink pure virtual function implementation.
       
   276 // Take RTP packet in the buffer and send it.
       
   277 // -----------------------------------------------------------------------------
       
   278 //
       
   279 void CMccRtpDataSink::EmptyBufferL( CMMFBuffer* aBuffer,
       
   280                                     MDataSource* aSupplier,
       
   281                                     TMediaId /*aMediaId*/,
       
   282                                     TRtpSendHeader& aHeaderInfo )
       
   283     {
       
   284     __ASSERT_ALWAYS( KNullId != iRtpStreamId, User::Leave( KErrNotReady ) );
       
   285     this->CheckBufferSupportL( aBuffer );
       
   286     User::LeaveIfNull( aSupplier );
       
   287     
       
   288     if ( SendingAllowed( aHeaderInfo ) )
       
   289         {
       
   290         __ASSERT_ALWAYS( iSender, User::Leave( KErrNotReady ) );
       
   291 
       
   292         TRACE_RTP_SINK_PRINT3( 
       
   293             "CMccRtpDataSink::EmptyBufferL, timestamp: %d, datalen: %d", 
       
   294             aHeaderInfo.iTimestamp, aBuffer->BufferSize() )
       
   295                                
       
   296         iBufferToBeEmptied = static_cast<CMMFDataBuffer*>( aBuffer );
       
   297 
       
   298         iSender->SendRtpPacketL( iRtpStreamId,
       
   299                                  aHeaderInfo, 
       
   300                                  iBufferToBeEmptied->Data() ); 
       
   301         ResetKeepaliveTimer();
       
   302         }
       
   303     else
       
   304         {
       
   305         TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::EmptyBufferL, PACKET DROPPED" )
       
   306         }
       
   307     
       
   308     // Buffer is emptied, notify the caller so it can reuse the buffer.
       
   309     // We risk a dead lock if we don't do this if the supplier relies on this
       
   310     // callback.
       
   311     aSupplier->BufferEmptiedL( aBuffer ); 
       
   312         
       
   313     #ifdef FTD_ENABLED
       
   314     TMccStreamStats stats;
       
   315     stats.iPacketsSent = ++iPacketsSent;
       
   316     stats.SetFieldUpdatedFlag( EPacketsSent );
       
   317     iStreamStatsQueue.Send( stats );
       
   318     #endif
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // CMccRtpDataSink::BufferFilledL
       
   323 // NOT SUPPORTED. MDataSink pure virtual function must be implemented.
       
   324 // -----------------------------------------------------------------------------
       
   325 //
       
   326 void CMccRtpDataSink::BufferFilledL( CMMFBuffer* /*aBuffer*/ )
       
   327     {
       
   328     // DataSource calls synchronously CMccRtpDataSink->EmptyBuffer(),
       
   329     // so DataSource->FillBuffer, CMccRtpDataSink->BufferFilledL chain is not used at the moment
       
   330     User::Leave( KErrNotSupported );
       
   331     }
       
   332 
       
   333 // -----------------------------------------------------------------------------
       
   334 // CMccRtpDataSink::CanCreateSinkBuffer
       
   335 // NOT SUPPORTED. MDataSink pure virtual function must be implemented.
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 TBool CMccRtpDataSink::CanCreateSinkBuffer()
       
   339     {
       
   340     return EFalse;
       
   341     }
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // CMccRtpDataSink::CreateSinkBufferL
       
   345 // NOT SUPPORTED. MDataSink pure virtual function must be implemented.
       
   346 // -----------------------------------------------------------------------------
       
   347 //
       
   348 CMMFBuffer* CMccRtpDataSink::CreateSinkBufferL( TMediaId /*aMediaId*/,
       
   349                                                 TBool& /*aReference*/ )
       
   350     {
       
   351     User::Leave( KErrNotSupported ); 
       
   352     return NULL;
       
   353     }
       
   354 
       
   355 // -----------------------------------------------------------------------------
       
   356 // CMccRtpDataSink::SinkPrimeL
       
   357 // Prime the sink. 
       
   358 // -----------------------------------------------------------------------------
       
   359 //
       
   360 void CMccRtpDataSink::SinkPrimeL()
       
   361     { 
       
   362     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SinkPrimeL" )
       
   363     
       
   364     SetStateL( ERtpStatePrimed );
       
   365     
       
   366     // Start sending keep alive packets. Secure session has to wait until
       
   367     // secure stream is created 
       
   368     if ( !iSecSession )
       
   369         {
       
   370         StartKeepaliveL( *iRtpMediaClock ); 
       
   371         }
       
   372         
       
   373     SendStreamEventToClient( KMccStreamPrepared );
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CMccRtpDataSink::SinkPlayL
       
   378 // Start the playout operation.
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 void CMccRtpDataSink::SinkPlayL()
       
   382     {
       
   383     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SinkPlayL IN" )
       
   384     if ( iSecureKeyExpired )
       
   385     	{
       
   386     	TRACE_RTP_SINK_PRINT( "Leave becuase the secure key expired" )
       
   387     	User::Leave( KErrGeneral );
       
   388     	}
       
   389     TMccRtpUser* user = FindRtpUserEntryForCurrent( *iEventHandler );
       
   390     __ASSERT_ALWAYS( user, User::Leave( KErrNotReady ) );
       
   391     
       
   392     SetStateL( ERtpStatePlaying );
       
   393     
       
   394     if ( user->iStartedOnce )
       
   395         {
       
   396         SendStreamEventToClient( KMccStreamResumed ); 
       
   397         }
       
   398     else
       
   399         {
       
   400         SendStreamEventToClient( KMccStreamStarted ); 
       
   401         user->iStartedOnce = ETrue;
       
   402         }
       
   403 
       
   404     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SinkPlayL OUT" )
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CMccRtpDataSink::SinkPauseL
       
   409 // Pauses the playout operation.
       
   410 // -----------------------------------------------------------------------------
       
   411 //
       
   412 void CMccRtpDataSink::SinkPauseL()
       
   413     {
       
   414     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SinkPauseL" )
       
   415     
       
   416     SetStateL( ERtpStatePaused );
       
   417     
       
   418     
       
   419     iSender->Clear();
       
   420     
       
   421     SendStreamEventToClient( KMccStreamPaused ); 
       
   422     }
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 // CMccRtpDataSink::SinkStopL
       
   426 // Stop the playout operation. 
       
   427 // -----------------------------------------------------------------------------
       
   428 //
       
   429 void CMccRtpDataSink::SinkStopL()
       
   430     {
       
   431     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SinkStopL" )
       
   432     
       
   433     SetStateL( ERtpStateStopped );
       
   434     
       
   435     StopKeepalive();
       
   436     
       
   437     iSender->Clear();
       
   438     
       
   439     SendStreamEventToClient( KMccStreamStopped ); 
       
   440     }
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 // CMccRtpDataSink::SendMediaSignallingL()
       
   444 // Sends media level signalling
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 void CMccRtpDataSink::SendMediaSignallingL( const TMccEvent& aEvent )
       
   448     {
       
   449     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SendMediaSignallingL" )
       
   450     
       
   451     __ASSERT_ALWAYS( aEvent.iEventCategory == KMccEventCategoryRtcp &&
       
   452                      aEvent.iEventType == KMccRtcpControl &&
       
   453                      iEnableRtcp,
       
   454                      User::Leave( KErrNotSupported ) );
       
   455                      
       
   456     __ASSERT_ALWAYS( iRtpAPI, User::Leave( KErrNotReady ) );
       
   457     
       
   458     const TMccRtcpEventData& rtcpEvent = 
       
   459         (*reinterpret_cast<const TMccRtcpEventDataPackage*>( 
       
   460             &aEvent.iEventData ))(); 
       
   461     
       
   462     switch ( rtcpEvent.iRtcpPacketType )
       
   463         {
       
   464         case KRtcpSdesPacket:
       
   465             {
       
   466             TPckgBuf<TRtpSdesParams> package;
       
   467             package.Copy( rtcpEvent.iRtcpPacketData );
       
   468             iRtpAPI->SetLocalSdes( package() );
       
   469             break;
       
   470             }   
       
   471         case KRtcpByePacket:
       
   472             {
       
   473 			__ASSERT_ALWAYS( KNullId != iRtpStreamId, User::Leave( KErrNotReady ) );
       
   474             User::LeaveIfError( 
       
   475                 iRtpAPI->SendRtcpByePacket( iRtpStreamId, 
       
   476                     rtcpEvent.iRtcpPacketData ) );
       
   477             break;
       
   478             }
       
   479         case KRtcpAppPacket:
       
   480             {
       
   481 			__ASSERT_ALWAYS( KNullId != iRtpStreamId, User::Leave( KErrNotReady ) );
       
   482 			
       
   483             TPckgBuf<TRtcpApp> package;
       
   484             package.Copy( rtcpEvent.iRtcpPacketData );
       
   485 			
       
   486             User::LeaveIfError( 
       
   487                 iRtpAPI->SendRtcpAppPacket( iRtpStreamId, package() ) );
       
   488             
       
   489             break;
       
   490             }
       
   491         case KRtcpSrPacket:
       
   492             {
       
   493             TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SendMediaSignallingL, SR" )
       
   494             	
       
   495             __ASSERT_ALWAYS( KNullId != iRtpStreamId, User::Leave( KErrNotReady ) ); 
       
   496             User::LeaveIfError( iRtpAPI->SendRtcpSrPacket( iRtpStreamId ) );
       
   497             break;
       
   498             }
       
   499         case KRtcpAnyPacket:
       
   500             {
       
   501             TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SendMediaSignallingL, FC" )
       
   502             TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::SendMediaSignallingL, sessionid:%d", 
       
   503                                    iSessionID )
       
   504             TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::SendMediaSignallingL, datalen: %d", 
       
   505                                    rtcpEvent.iRtcpPacketData.Length() )
       
   506             
       
   507             __ASSERT_ALWAYS( iSender, User::Leave( KErrNotReady ) );
       
   508             TBool useRTPSocket( EFalse );
       
   509             iSender->SendDataL( iSessionID,
       
   510                                 useRTPSocket,
       
   511                                 rtcpEvent.iRtcpPacketData );
       
   512             break;
       
   513             }
       
   514         default:
       
   515             {
       
   516             TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SendMediaSignallingL, default" )
       
   517             User::Leave( KErrArgument );
       
   518             break;
       
   519             }
       
   520         }
       
   521     }
       
   522 
       
   523 // -----------------------------------------------------------------------------
       
   524 // CMccRtpDataSink::DoCreateStreamL
       
   525 // Creates a transmit stream.
       
   526 // -----------------------------------------------------------------------------
       
   527 //
       
   528 void CMccRtpDataSink::DoCreateStreamL()
       
   529     {
       
   530     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::DoCreateStreamL IN" )
       
   531     __ASSERT_ALWAYS( KNullId == iRtpStreamId, User::Leave( KErrAlreadyExists ) );
       
   532     __ASSERT_ALWAYS( NULL != iRtpAPI, User::Leave( KErrNotReady ) );
       
   533     
       
   534     if ( !iSender )
       
   535         {
       
   536         // Can do marker based cleanup only with video stream
       
   537         TBool doMarkerBasedCleanup( iMedia.iMediaType == KUidMediaTypeVideo );
       
   538         iSender = CMccRtpSender::NewL( 
       
   539                         *this, *iRtpAPI, iSessionID, doMarkerBasedCleanup );
       
   540         }
       
   541     
       
   542     TTranStreamParams transParams;
       
   543     transParams.iPayloadType = iCodecInfo.iPayloadType;
       
   544     iRtpStreamId =
       
   545     	iRtpAPI->CreateTransmitStreamL( iSessionID, transParams, iSSRC ); 
       
   546     
       
   547     if ( KNullId == iRtpStreamId )
       
   548         {
       
   549         TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::DoCreateStreamL KErrCouldNotConnect 1" )
       
   550         
       
   551         User::Leave( KErrCouldNotConnect );
       
   552         }
       
   553         
       
   554     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::DoCreateStreamL SetSamplingRate 1" ) 
       
   555         
       
   556     User::LeaveIfError( iRtpAPI->SetSamplingRate( 
       
   557         iCodecInfo.iPayloadType, KDefSampleRate ) );
       
   558 
       
   559     if ( KMccPayloadTypeMax != iCodecInfo.iRedundantPayload )
       
   560         {
       
   561         User::LeaveIfError( iRtpAPI->SetSamplingRate( 
       
   562             iCodecInfo.iRedundantPayload, KDefSampleRate ) );
       
   563         }
       
   564    
       
   565     DoCreateSrtpStreamL();
       
   566             
       
   567   	TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::DoCreateStreamL OUT" )
       
   568     }
       
   569 
       
   570 // -----------------------------------------------------------------------------
       
   571 // CMccRtpDataSink::SendErrorOccured
       
   572 // Asynchronous sending error occured
       
   573 // -----------------------------------------------------------------------------
       
   574 //    
       
   575 void CMccRtpDataSink::SendErrorOccured( TInt aError )
       
   576     {
       
   577     TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::SendErrorOccured, err: %d", aError )
       
   578     
       
   579     SendInternalRtpEventToAllClients( iUsers,
       
   580                                       KMccRtpSinkUid, 
       
   581                                       EMccInternalRtpSinkError, 
       
   582                                       KMccStreamError,
       
   583                                       MCC_RTPSINK_ENDPOINT_ID,
       
   584                                       aError );
       
   585     
       
   586     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SendErrorOccured, exit" )
       
   587     }
       
   588 
       
   589 // -----------------------------------------------------------------------------
       
   590 // CMccRtpDataSink::DoCreateSrtpStreamL
       
   591 // -----------------------------------------------------------------------------
       
   592 //
       
   593 void CMccRtpDataSink::DoCreateSrtpStreamL()
       
   594 	{
       
   595 	TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::DoCreateSrtpStreamL IN" )
       
   596     if ( !iSrtpStream && iContext && iSecSession && KNullId != iRtpStreamId )
       
   597         {
       
   598         TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::DoCreateSrtpStreamL, creating" )
       
   599         iSrtpStream = CSRTPStreamOut::NewL( 
       
   600             *iSecSession, static_cast<TUint>( iSSRC ), iContext, *this );
       
   601         
       
   602         // Now it's possible to send keepalive
       
   603         StartKeepaliveL( *iRtpMediaClock );
       
   604         }
       
   605     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::DoCreateSrtpStreamL OUT" )
       
   606 	}
       
   607 	
       
   608 // ---------------------------------------------------------------------------
       
   609 // CMccRtpDataSink::SinkCustomCommand()
       
   610 // 
       
   611 // ---------------------------------------------------------------------------
       
   612 //
       
   613 void CMccRtpDataSink::SinkCustomCommand( TMMFMessage& aMessage )
       
   614     {
       
   615     TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::SinkCustomCommand - FUNCTION: %d",
       
   616             aMessage.Function() )
       
   617 
       
   618     TInt result( KErrNone );
       
   619     aMessage.Complete( result );
       
   620     }
       
   621 
       
   622 // ---------------------------------------------------------------------------
       
   623 // CMccRtpDataSink::SendRTCPData()
       
   624 // Sends Non-RTCP data
       
   625 // ---------------------------------------------------------------------------
       
   626 //    
       
   627 void CMccRtpDataSink::SendRTCPDataL( const TDesC8& aData )
       
   628     {
       
   629     if ( iRtpAPI && iSender )
       
   630         {
       
   631         TBool useRTPSocket( EFalse );
       
   632         iSender->SendDataL( iSessionID, useRTPSocket, aData );
       
   633         }
       
   634     else
       
   635         {
       
   636         User::Leave( KErrNotReady );
       
   637         }
       
   638     }
       
   639 
       
   640 // -----------------------------------------------------------------------------
       
   641 // CMccRtpDataSink::HandleBySsrc
       
   642 // -----------------------------------------------------------------------------
       
   643 //   
       
   644 TBool CMccRtpDataSink::HandleBySsrc( const TRtpSSRC& aSsrc )
       
   645     {
       
   646     return ( iSSRC == aSsrc );
       
   647     }
       
   648     
       
   649 // -----------------------------------------------------------------------------
       
   650 // CMccRtpDataSink::RtpStreamId
       
   651 // -----------------------------------------------------------------------------
       
   652 //    
       
   653 TRtpId CMccRtpDataSink::RtpStreamId()
       
   654     {
       
   655     return iRtpStreamId;
       
   656     }
       
   657     
       
   658 // -----------------------------------------------------------------------------
       
   659 // CMccRtpDataSink::IsSink
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 TBool CMccRtpDataSink::IsSink() const
       
   663     {
       
   664     return ETrue;
       
   665     }
       
   666 
       
   667 // -----------------------------------------------------------------------------
       
   668 // CMccRtpDataSink::IsSending
       
   669 // -----------------------------------------------------------------------------
       
   670 //        
       
   671 TBool CMccRtpDataSink::IsSending() const
       
   672     {
       
   673     return ( ERtpStatePlaying == State() );
       
   674     }
       
   675 
       
   676 // -----------------------------------------------------------------------------
       
   677 // CMccRtpDataSink::SendStreamEventToClient()
       
   678 // -----------------------------------------------------------------------------
       
   679 //	
       
   680 void CMccRtpDataSink::SendStreamEventToClient( 
       
   681     TMccEventType aEventType,
       
   682     TInt aError )
       
   683     {
       
   684     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSink::SendStreamEventToClient" )
       
   685     
       
   686     if ( iEventHandler )
       
   687 	    {
       
   688 	    TMccEvent event( 0, 
       
   689 	                     0, 
       
   690 	                     0, 
       
   691 	                     MCC_ENDPOINT_ID( static_cast<MDataSink*>( this ) ), 
       
   692 	                     KMccEventCategoryStream, 
       
   693 	                     aEventType, 
       
   694 	                     aError, 
       
   695 	                     KNullDesC8 );
       
   696 
       
   697 		TMccInternalEvent internalEvent( KMccRtpSinkUid, 
       
   698 		                                 EMccInternalEventNone,
       
   699 		                                 event );
       
   700 		                         
       
   701 		iEventHandler->SendEventToClient( internalEvent );
       
   702 	    }
       
   703 	else
       
   704 		{
       
   705 		TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSink::SendStreamEventToClient, \
       
   706 		iEventHandler=NULL" )
       
   707 		}
       
   708     }
       
   709  
       
   710 // ---------------------------------------------------------------------------
       
   711 // CMccRtpDataSink::FindRtpUserEntryForCurrent
       
   712 // ---------------------------------------------------------------------------
       
   713 //
       
   714 TMccRtpUser* CMccRtpDataSink::FindRtpUserEntryForCurrent( 
       
   715     MAsyncEventHandler& aEventHandler )
       
   716     {
       
   717     TMccRtpUser entry( &aEventHandler );
       
   718     TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch );
       
   719     TInt index = iUsers.Find( entry, comparison );
       
   720     if ( index != KErrNotFound )
       
   721         {
       
   722         return &iUsers[ index ];
       
   723         }
       
   724     return NULL;
       
   725     }
       
   726 
       
   727 // ---------------------------------------------------------------------------
       
   728 // CMccRtpDataSink::RemoveCurrentRtpUser
       
   729 // ---------------------------------------------------------------------------
       
   730 //
       
   731 void CMccRtpDataSink::RemoveCurrentRtpUser()
       
   732     {
       
   733     TMccRtpUser entry( iEventHandler );
       
   734     TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch );
       
   735     TInt index = iUsers.Find( entry, comparison );
       
   736     if ( index != KErrNotFound )
       
   737         {
       
   738         iUsers.Remove( index );
       
   739         }
       
   740     }
       
   741         
       
   742 // ---------------------------------------------------------------------------
       
   743 // CMccRtpDataSink::RtpUserMatch
       
   744 // ---------------------------------------------------------------------------
       
   745 //   
       
   746 TBool CMccRtpDataSink::RtpUserMatch( 
       
   747     const TMccRtpUser& aUser1, 
       
   748     const TMccRtpUser& aUser2 )
       
   749     {
       
   750     // First argument is always the search term
       
   751     
       
   752     TBool match( EFalse );
       
   753     if ( aUser1.iEventHandler )
       
   754         {
       
   755         match = ( aUser1.iEventHandler == aUser2.iEventHandler );
       
   756         }
       
   757     return match;
       
   758     }
       
   759 
       
   760 // ---------------------------------------------------------------------------
       
   761 // CMccRtpDataSink::SendingAllowed
       
   762 // ---------------------------------------------------------------------------
       
   763 //   
       
   764 TBool CMccRtpDataSink::SendingAllowed( 
       
   765         const TRtpSendHeader& aHeaderInfo ) const
       
   766     {
       
   767     // If secure session, srtp stream has to exist
       
   768     TRACE_RTP_SINK_PRINT2( "CMccRtpDataSink::Sending allowed iSecureKeyExpired = ",
       
   769         iSecureKeyExpired )
       
   770     
       
   771     TBool isPayloadMuted 
       
   772         = iMuteOn ? aHeaderInfo.iPayloadType != iExceptionPt : EFalse;
       
   773     
       
   774     return ( ERtpStatePlaying == State() && 
       
   775              ( !iSecSession || iSrtpStream ) &&
       
   776     		 !iSecureKeyExpired && 
       
   777     		 !isPayloadMuted );
       
   778     }
       
   779 
       
   780 // ---------------------------------------------------------------------------
       
   781 // CMccRtpDataSink::SetMediaClock
       
   782 // ---------------------------------------------------------------------------
       
   783 //    
       
   784 void CMccRtpDataSink::SetMediaClock( CMccRtpMediaClock& aRtpMediaClock )
       
   785     {
       
   786     TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SetMediaClock" )
       
   787     
       
   788     if ( !iRtpMediaClock )
       
   789         {
       
   790         iRtpMediaClock = &aRtpMediaClock;
       
   791         }
       
   792     else
       
   793         {
       
   794         TRACE_RTP_SINK_PRINT( "CMccRtpDataSink::SetMediaClock - Allready set!" )
       
   795         }
       
   796     }
       
   797 
       
   798 // ---------------------------------------------------------------------------
       
   799 // FROM SRTP API
       
   800 // This function is called by SRTP Stream initiated with 
       
   801 // MSRTPReKeyingObserver when a master key is stale and needs 
       
   802 // to be refreshed.  
       
   803 // ---------------------------------------------------------------------------
       
   804 //
       
   805 void CMccRtpDataSink::SRTPMasterKeyStaleEvent( const CSRTPStream& aStream )
       
   806     {
       
   807     TRACE_RTP_INTERFACE_PRINT( "CMccRtpDataSink::SRTPMasterKeyStaleEvent" )
       
   808     
       
   809     if ( iSrtpStream == &aStream )
       
   810         {
       
   811         iSecureKeyExpired = ETrue;
       
   812         SendSecureRtpEventToClient( iEventHandler,
       
   813                                     KMccRtpSinkUid,
       
   814                                     EMccInternalEventNone,
       
   815                                     KMccMasterKeyStaled,
       
   816                                     MCC_RTPSINK_ENDPOINT_ID );   
       
   817         }
       
   818     else
       
   819         {
       
   820         TRACE_RTP_INTERFACE_PRINT( "CMccRtpDataSink::SRTPMasterKeyStaleEvent - Wrong stream" )
       
   821         }
       
   822     }
       
   823 
       
   824 // ---------------------------------------------------------------------------
       
   825 // FROM SRTP API
       
   826 // This function is called by SRTP Stream initiated with 
       
   827 // CSRTPSession  when a master key is stale and
       
   828 // needs to be refreshed.  
       
   829 // ---------------------------------------------------------------------------
       
   830 void CMccRtpDataSink::SRTPMasterKeyStaleEvent(const CSRTPSession& aSession )
       
   831     {
       
   832     TRACE_RTP_INTERFACE_PRINT( "CMccRtpStream::SRTPMasterKeyStaleEvent" )
       
   833     
       
   834     if ( iSecSession == &aSession )
       
   835         {
       
   836         iSecureKeyExpired = ETrue;
       
   837         SendSecureRtpEventToClient( iEventHandler,
       
   838                                     KMccRtpSinkUid,
       
   839                                     EMccInternalEventNone,
       
   840                                     KMccMasterKeyStaled,
       
   841                                     MCC_RTPSINK_ENDPOINT_ID );    
       
   842         }
       
   843     else
       
   844         {
       
   845          TRACE_RTP_INTERFACE_PRINT( "MccRtpStream::SRTPMasterKeyStaleEvent - Wrong session" )
       
   846         }
       
   847     } 
       
   848     
       
   849 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   850 
       
   851 //  End of File  
       
   852