rtp/rtpstack/src/rtprecvstream.cpp
changeset 0 307788aac0a8
child 29 5f12516512fa
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 /*
       
     2 * Copyright (c) 2002-2003 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 
       
    20 
       
    21 #include "rtprecvstream.h"
       
    22  
       
    23 
       
    24 
       
    25 // ---------------------------------------------------------------------------
       
    26 // C++ default constructor can NOT contain any code, that
       
    27 // might leave.
       
    28 // ---------------------------------------------------------------------------
       
    29 //
       
    30 CRtpRecvStream::CRtpRecvStream( MSsrcCheckCallback* aCallback,
       
    31                                 const TRtpPayloadType aPayloadType,
       
    32                                 const TRtpId aSessionId,
       
    33                                 const TRtpId aReceiveStreamId,
       
    34                                 MRtpObserver** aRtpObserver,
       
    35                                 MRtcpObserver* aRtcpObserver,
       
    36                                 const TUint32* aProfileRTPTimeRates )
       
    37     :
       
    38     CRtpStream( aReceiveStreamId,
       
    39              aSessionId,
       
    40              aProfileRTPTimeRates,
       
    41              aRtcpObserver,
       
    42              aPayloadType ),
       
    43     iNumWrapAround( 0 ),
       
    44     iRtpObserver( aRtpObserver ),
       
    45     iCallback( aCallback )
       
    46     {
       
    47     // set syncInfo values to zero 
       
    48     RtpStreamJitterInit();
       
    49     RtpStreamSyncInfoInit();
       
    50     }
       
    51 
       
    52 // ---------------------------------------------------------------------------
       
    53 // Symbian 2nd phase constructor can leave.
       
    54 // ---------------------------------------------------------------------------
       
    55 //
       
    56 void CRtpRecvStream::ConstructL()
       
    57     {
       
    58     iRemoteSDES = CRtpSDES::NewL();
       
    59     }
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // Two-phased constructor.
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CRtpRecvStream* CRtpRecvStream::NewL( const TRtpPayloadType aPayloadType,
       
    66                                       const TRtpId aSessionId,
       
    67                                       const TRtpId aReceiveStreamId,
       
    68                                       MRtpObserver** aRtpObserver,
       
    69                                       MRtcpObserver* aRtcpObserver,
       
    70                                       const TUint32* aProfileRTPTimeRates,
       
    71                                       MSsrcCheckCallback* aCallback )
       
    72     {
       
    73     CRtpRecvStream* self =
       
    74         new ( ELeave ) CRtpRecvStream( aCallback,
       
    75                                        aPayloadType,
       
    76                                        aSessionId,
       
    77                                        aReceiveStreamId,
       
    78                                        aRtpObserver,
       
    79                                        aRtcpObserver,
       
    80                                        aProfileRTPTimeRates );
       
    81     CleanupStack::PushL( self );
       
    82     self->ConstructL();
       
    83     CleanupStack::Pop(); // self 
       
    84     return self;
       
    85     }
       
    86 
       
    87 // ---------------------------------------------------------------------------
       
    88 // Destructor
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 CRtpRecvStream::~CRtpRecvStream()
       
    92     {
       
    93 	delete iRemoteSDES;
       
    94     }
       
    95 
       
    96 
       
    97 // ---------------------------------------------------------------------------
       
    98 // RegisterRtpObserver
       
    99 // ---------------------------------------------------------------------------
       
   100 //
       
   101 void CRtpRecvStream::RegisterRtpObserver(MRtpObserver* aRtpObserver)
       
   102     {
       
   103     *iRtpObserver = aRtpObserver; 
       
   104     }
       
   105 
       
   106 
       
   107 // ---------------------------------------------------------------------------
       
   108 // UnRegisterRtpObserver
       
   109 // ---------------------------------------------------------------------------
       
   110 //
       
   111 void CRtpRecvStream::UnRegisterRtpObserver()
       
   112     {
       
   113     *iRtpObserver = NULL;
       
   114     }
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 // TInt CRtpRecvStream::ResetStreamStat()
       
   118 // ---------------------------------------------------------------------------
       
   119 //
       
   120 TInt CRtpRecvStream::ResetStreamStat()
       
   121     {
       
   122     TRtcpStats rtcpStat;
       
   123 
       
   124     RtcpStats( rtcpStat );
       
   125     
       
   126     rtcpStat.iRtcpReceiverStats.iFractionLost = 0;
       
   127     rtcpStat.iRtcpReceiverStats.iCumNumPacketsLost = 0;
       
   128     rtcpStat.iRtcpReceiverStats.iSeqNumReceived = 0; 
       
   129     rtcpStat.iRtcpReceiverStats.iArrivalJitter = 0;
       
   130     rtcpStat.iRtcpReceiverStats.iRoundTripDelay = 0;
       
   131     rtcpStat.iRtcpReceiverStats.iChannelBufferSize = 0;
       
   132    
       
   133     // The sender stats are updated when receiving SR packets, so reset 
       
   134     rtcpStat.iRtcpSenderStats.iSSRC = 0;
       
   135     rtcpStat.iRtcpSenderStats.iCumNumOctetsSent = 0;
       
   136     rtcpStat.iRtcpSenderStats.iNumPacketsSent = 0;
       
   137     rtcpStat.iRtcpSenderStats.iNTPTimeStampSec = 0;
       
   138     rtcpStat.iRtcpSenderStats.iNTPTimeStampFrac = 0;
       
   139     rtcpStat.iRtcpSenderStats.iTimeStamp = 0;
       
   140 
       
   141     iRtcpStats = rtcpStat;
       
   142     
       
   143     iNumReceivedPackets = 0;
       
   144     iNumWrapAround = 0;   
       
   145     
       
   146     // set syncInfo values to zero 
       
   147     RtpStreamJitterInit();
       
   148     RtpStreamSyncInfoInit();
       
   149     
       
   150     return KErrNone;
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // TInt CRtpTranStream::GetStreamStat()
       
   155 // 
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 TInt CRtpRecvStream::GetStreamStat( TRtpPeerStat& aStat )
       
   159     {
       
   160     TRtcpStats rtcpStat;
       
   161 
       
   162     RtcpStats( rtcpStat );
       
   163 
       
   164     aStat.iCumNumOctetsSent = rtcpStat.iRtcpSenderStats.iCumNumOctetsSent;
       
   165     aStat.iNumPacketsSent = rtcpStat.iRtcpSenderStats.iNumPacketsSent;
       
   166 
       
   167     aStat.iTxBandwidth = rtcpStat.iRtcpReceiverStats.iTxBandwidth;
       
   168     aStat.iArrivalJitter = rtcpStat.iRtcpReceiverStats.iArrivalJitter;
       
   169     aStat.iCumNumPacketsLost = rtcpStat.iRtcpReceiverStats.iCumNumPacketsLost;
       
   170     aStat.iFractionLost = rtcpStat.iRtcpReceiverStats.iFractionLost;
       
   171     aStat.iRoundTripDelay = rtcpStat.iRtcpReceiverStats.iRoundTripDelay;
       
   172     aStat.iRxBandwidth = rtcpStat.iRtcpReceiverStats.iBandwidth;
       
   173     aStat.iChannelBufferSize = rtcpStat.iRtcpReceiverStats.iChannelBufferSize;
       
   174     aStat.iNTPTimeStampSec = 0;
       
   175     aStat.iNTPTimeStampFrac = 0;
       
   176     aStat.iTimeStamp = 0;
       
   177 
       
   178     return KErrNone;
       
   179     }
       
   180 
       
   181 // ---------------------------------------------------------------------------
       
   182 // TInt CRtpRecvStream::RtpStreamProcessRtpPacketL()
       
   183 // 
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 TInt CRtpRecvStream::RtpStreamProcessRtpPacketL( CRtpPacket* aPktRcv, TBool aAssignStream )
       
   187     {
       
   188     RTP_DEBUG_DETAIL( "CRtpRecvStream::RtpStreamProcessRtpPacketL Entry" );
       
   189     aPktRcv->RtpPacketResetPtr();
       
   190 
       
   191     // Check if this packet belongs to this stream by looking at the source SSRC
       
   192     if ( !aAssignStream )
       
   193         {
       
   194         TRtpSSRC aRemoteSSRC( NULL );
       
   195         aPktRcv->SetType( ERTP );
       
   196         aRemoteSSRC = aPktRcv->RtpPacketGetSSRC();
       
   197         if ( iRemoteSSRC != aRemoteSSRC )
       
   198             {
       
   199             RTP_DEBUG_DETAIL( "RtpRecvStream: Wrong SSRC" );
       
   200             return KErrNotFound;
       
   201             }
       
   202         }
       
   203     else
       
   204         {
       
   205         //assigned RTP packet SSRC if this stream's remote SSRC is NULL
       
   206         // if it is not null then return KErrNotFound
       
   207         if ( iRemoteSSRC )
       
   208             {
       
   209             RTP_DEBUG_DETAIL( "RtpRecvStream: Did not expect own SSRC" );
       
   210             return KErrNotFound;
       
   211             }
       
   212         }
       
   213 
       
   214     TRtpPacketStreamParam streamParam;
       
   215     TRtpPacketIOParam extractParam;
       
   216 
       
   217     // process RTP packet
       
   218     aPktRcv->SetType( ERTP );
       
   219 
       
   220     extractParam.TRTP.extension.data = NULL;
       
   221 
       
   222     if ( aPktRcv->RtpPacketProcessL( &streamParam, &extractParam ) < 0 )
       
   223         {
       
   224         RTP_DEBUG_DETAIL( "Invalid Rtp packet is received" );
       
   225         return KErrCorrupt;
       
   226         }
       
   227 	if (!iCallback->CheckRemoteAddr())
       
   228 		{
       
   229 		RTP_DEBUG_DETAIL( "Packet comes from wrong remote address" );
       
   230 		return KErrNotFound;
       
   231 		}
       
   232     // update and check stream parameters
       
   233     if ( RtpStreamUpdateParamL( aPktRcv->Type(), &streamParam ) < 0 )
       
   234         {
       
   235         
       
   236         RTP_DEBUG_PACKET("RtpRecvStream: Could not update params" );
       
   237         
       
   238         return KErrNotFound;
       
   239         }
       
   240 
       
   241     iHdr.iPadding = extractParam.TRTP.padding;
       
   242     iHdr.iExtension = extractParam.TRTP.fHeaderExtension;
       
   243     iHdr.iCsrcCount = extractParam.TRTP.numCSRC;
       
   244 
       
   245     iHdr.iMarker = extractParam.TRTP.marker;
       
   246     iHdr.iTimestamp = streamParam.TRTP.timeStamp;
       
   247     iHdr.iPayloadType = streamParam.TRTP.payload; // iPayload; pass payload type to app,even if it changed
       
   248 
       
   249     if ( iHdr.iExtension )
       
   250         {
       
   251 		iHdr.iHeaderExtension = &iHeaderExtension;
       
   252         iHdr.iHeaderExtension->iType = extractParam.TRTP.extension.type;
       
   253         iHdr.iHeaderExtension->iLength = extractParam.TRTP.extension.length;
       
   254         iHdr.iHeaderExtension->iData = extractParam.TRTP.extension.data;
       
   255         }
       
   256 
       
   257     iFlagReceivedRTPPackets = ETrue;
       
   258 
       
   259     // calculate jitter, maybe it eats a big portion of CPU time?
       
   260     RtpStreamUpdateJitter( iHdr.iTimestamp );
       
   261 
       
   262     iHdr.iSeqNum = streamParam.TRTP.seqNum;
       
   263     
       
   264     RTP_DEBUG_DETAIL_DVALUE( "The received RTP packet size = ", extractParam.TRTP.payloadDataLen );
       
   265     RTP_DEBUG_DETAIL_DVALUE( "The received RTP packet Seq Num = ", streamParam.TRTP.seqNum );
       
   266     
       
   267     TPtrC8 payloadData( extractParam.TRTP.payloadData, extractParam.TRTP.payloadDataLen );
       
   268 
       
   269     if ( *iRtpObserver )
       
   270         {
       
   271         RTP_DEBUG_PACKET("RTP packet received and pass to upper application" );
       
   272         
       
   273         (*iRtpObserver)->RtpPacketReceived( iStreamId, iHdr, payloadData );
       
   274         }
       
   275     else
       
   276         {
       
   277         RTP_DEBUG_PACKET( "RtpRecvStream: No observer registered" );
       
   278         }
       
   279    	if(aPktRcv->iExdataAlloc )
       
   280       	{
       
   281        	User::Free( extractParam.TRTP.extension.data );
       
   282        	}
       
   283    	if (aPktRcv->iCsrcAlloc)
       
   284    		{
       
   285    		User::Free( extractParam.TRTP.CSRCarray);
       
   286    		}    
       
   287    	RTP_DEBUG_DETAIL( "CRtpRecvStream::RtpStreamProcessRtpPacketL Exit" );
       
   288     	
       
   289     return KErrNone;
       
   290     }
       
   291 
       
   292 
       
   293 
       
   294 // ---------------------------------------------------------------------------
       
   295 // CRtpRecvStream::RtpStreamSyncInfoInit()
       
   296 // For receiving stream, iSyncInfo is initialized to zero
       
   297 // and will be updated by SR received for the future RR creating
       
   298 // iSyncInfo.timeStamp & iSyncInfo.lastUpdateLocalTime are
       
   299 // not useful actually.
       
   300 // ---------------------------------------------------------------------------
       
   301 // 
       
   302 void CRtpRecvStream::RtpStreamSyncInfoInit()
       
   303     {
       
   304     iSyncInfo.iNTPTimeStampFrac = 0;
       
   305     iSyncInfo.iNTPTimeStampSec = 0;
       
   306     iSyncInfo.iTimeStamp = 0;
       
   307     iSyncInfo.iLastUpdateLocalTime = 0;
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // CRtpRecvStream::RtpStreamJitterInit()
       
   312 // 
       
   313 // ---------------------------------------------------------------------------
       
   314 //
       
   315 void CRtpRecvStream::RtpStreamJitterInit()
       
   316     {
       
   317     iSyncJitter.iLastPacketS = 0;
       
   318     iSyncJitter.iLastPacketR = 0;
       
   319     iSyncJitter.iJitterTime = 0;
       
   320 
       
   321     iSyncJitter.iWaitTime = 0;
       
   322     }
       
   323 
       
   324 // ---------------------------------------------------------------------------
       
   325 // CRtpRecvStream::RtpStreamUpdateJitter()
       
   326 // 
       
   327 // ---------------------------------------------------------------------------
       
   328 //
       
   329 void CRtpRecvStream::RtpStreamUpdateJitter( TRtpTimeStamp aCurrentTimeStamp )
       
   330     {
       
   331     TUint32 gtTime = TRtpUtil::GtGetTime();
       
   332     TRtpTimeStamp packetRTP( aCurrentTimeStamp );
       
   333     TInt jitterTime = 0;
       
   334 
       
   335     if ( packetRTP == iSyncJitter.iLastPacketS )
       
   336         {
       
   337         return;
       
   338         }
       
   339 
       
   340     jitterTime = ( ( ( gtTime - iSyncJitter.iLastPacketR ) * iSyncJitter.iTimeStampResolution ) 
       
   341                  / KTenthOfmsPerSecond ) - ( packetRTP - iSyncJitter.iLastPacketS );
       
   342 
       
   343     iSyncJitter.iJitterTime = iSyncJitter.iJitterTime + 
       
   344         ( ( ( TReal64 ) Abs( jitterTime ) - iSyncJitter.iJitterTime ) / 16.0 );
       
   345 
       
   346     // if jitter > 100 seconds, reset it. 
       
   347     if ( iSyncJitter.iJitterTime > 1000000 ) // 100 * KTenthOfmsPerSecond 
       
   348         {
       
   349         iSyncJitter.iJitterTime = 0;
       
   350         }
       
   351     iSyncJitter.iLastPacketR = gtTime;
       
   352     iSyncJitter.iLastPacketS = packetRTP;
       
   353     }
       
   354 
       
   355 // ---------------------------------------------------------------------------
       
   356 // TInt CRtpRecvStream::RtpStreamUpdateParamL()
       
   357 // 
       
   358 // ---------------------------------------------------------------------------
       
   359 //
       
   360 TInt CRtpRecvStream::RtpStreamUpdateParamL( TRtpPacketType aPType, 
       
   361                                            TRtpPacketStreamParam* aStreamParam )
       
   362     {
       
   363     TUint32 timerate;
       
   364     TInt error( KErrNone );
       
   365 
       
   366     if ( aPType == ERTP )
       
   367         {
       
   368         // Check if there is an SSRC collision
       
   369         if ( iCallback )
       
   370             {
       
   371             error = iCallback->CheckRemoteSsrcL( aStreamParam->TRTP.SSRC );
       
   372             }
       
   373         if ( error < KErrNone )
       
   374             {
       
   375             return KErrCorrupt;
       
   376             }
       
   377         if ( error > KErrNone )
       
   378             {
       
   379             // There was an SSRC collision, and TRTP.SSRC now contains the
       
   380             // updated SSRC value.
       
   381             iRemoteSSRC = aStreamParam->TRTP.SSRC;
       
   382             }
       
   383 
       
   384         if ( iFlagFirstPkg )
       
   385             {
       
   386             iRemoteSSRC = aStreamParam->TRTP.SSRC;
       
   387             iPayload = aStreamParam->TRTP.payload;
       
   388             iBaseSeqNum = aStreamParam->TRTP.seqNum;
       
   389 
       
   390             timerate = *( iProfileRTPTimeRates + iPayload );
       
   391             if ( timerate != 0 )
       
   392                 {
       
   393                 iSyncJitter.iTimeStampResolution = KMicrosecondPerSecond / timerate;
       
   394                 }
       
   395             else
       
   396                 {
       
   397                 iSyncJitter.iTimeStampResolution = 0;
       
   398                 }
       
   399             }
       
   400         else if ( iRemoteSSRC != aStreamParam->TRTP.SSRC )
       
   401             {
       
   402             // SSRC and seqNum change. start monitoring if this change is intentional, 
       
   403             // if several packets received sequentionally, and then re-initialize the stream 
       
   404             
       
   405             RTP_DEBUG_DETAIL( "SSRC changed" );
       
   406             
       
   407             
       
   408             return KErrNotFound;
       
   409             }
       
   410         else
       
   411             {
       
   412             if ( iPayload != aStreamParam->TRTP.payload )
       
   413                 {
       
   414                 // payload type changed, inform application somehow 
       
   415                 RTP_DEBUG_DETAIL( "payload type changed" );
       
   416                 
       
   417                 }
       
   418             }
       
   419 
       
   420         if ( aStreamParam->TRTP.seqNum == TRtpUtil::Min16( aStreamParam->TRTP.seqNum, iSeqNum ) && !iFlagFirstPkg )
       
   421             {
       
   422             // if there is no buffering, out of order and duplicate packets
       
   423             // have to be discarded
       
   424             return KErrNone; // give this packet to the application as there is no buffer in RTP
       
   425             }
       
   426         else
       
   427             {
       
   428             //update the highest received SN and TS
       
   429             if ( TRtpUtil::Wrap16( iSeqNum, aStreamParam->TRTP.seqNum ) && !iFlagFirstPkg )
       
   430                 {
       
   431                 iSeqNumCycles++;
       
   432                 }
       
   433             iSeqNum = aStreamParam->TRTP.seqNum;
       
   434             iTimeStamp = aStreamParam->TRTP.timeStamp;
       
   435             iFlagFirstPkg = 0;
       
   436             iNumReceivedPackets++;
       
   437             }
       
   438         }
       
   439     else
       
   440         {
       
   441         return KErrNotFound;
       
   442         }
       
   443 
       
   444     return KErrNone;
       
   445     } 
       
   446 
       
   447 
       
   448 // ---------------------------------------------------------------------------
       
   449 // CRtpRecvStream::RtpStreamCreateRtcpReportSection()
       
   450 // For receiving stream, it only creates RR packet
       
   451 // ---------------------------------------------------------------------------
       
   452 // 
       
   453 void CRtpRecvStream::RtpStreamCreateRtcpReportSection( CRtpPacket* aPkt )
       
   454     {
       
   455     TRtpPacketStreamParam streamParam;
       
   456     TRtpPacketIOParam inParam;
       
   457 
       
   458     TUint32 numPacketsExpected;
       
   459     TUint32 numPacketsIntervalLost;
       
   460     TUint32 numPacketsIntervalExpected;
       
   461 
       
   462     streamParam.TRTCP_RR.SSRC = iRemoteSSRC;
       
   463 
       
   464     // iSeqNum is 16 bit, but streamParam.TRTCP_RR.seqNumReceived is 32 bits. 
       
   465     // Check RFC1889 for RTCP part 
       
   466 
       
   467     streamParam.TRTCP_RR.seqNumReceived = iSeqNum + ( iSeqNumCycles << 16 );
       
   468     numPacketsExpected = streamParam.TRTCP_RR.seqNumReceived - iBaseSeqNum + 1;
       
   469 
       
   470     if ( numPacketsExpected < iNumReceivedPackets )
       
   471         {
       
   472         streamParam.TRTCP_RR.cumNumPacketsLost = 0;
       
   473         }
       
   474     else
       
   475         {
       
   476         if ( ( numPacketsExpected + ( 1 << 16 ) * iNumWrapAround ) < iLastRR_numExpectedPackets )
       
   477             {
       
   478             iNumWrapAround++;
       
   479             numPacketsExpected += ( 1 << 16 ) * iNumWrapAround;
       
   480             }
       
   481         else
       
   482             {
       
   483             numPacketsExpected += ( 1 << 16 ) * iNumWrapAround;
       
   484             }
       
   485         streamParam.TRTCP_RR.cumNumPacketsLost = numPacketsExpected - iNumReceivedPackets;
       
   486         }
       
   487 
       
   488     numPacketsIntervalExpected = numPacketsExpected - iLastRR_numExpectedPackets;
       
   489     numPacketsIntervalLost = numPacketsIntervalExpected - ( iNumReceivedPackets - iLastRR_numReceivedPackets );
       
   490 
       
   491     //
       
   492     // From RFC 1889
       
   493     // fraction lost: 8 bits
       
   494     // The fraction of RTP data packets from source SSRC_n lost since the previous SR or RR packet was sent, 
       
   495     // expressed as a fixed point number with the binary point at the left edge of the field. (That is 
       
   496     // equivalent to taking the integer part after multiplying the loss fraction by 256.) This fraction is
       
   497     // defined to be the number of packets lost divided by the number of packets expected.
       
   498     //
       
   499 
       
   500     if ( ( numPacketsIntervalExpected == 0 ) || ( numPacketsIntervalLost == 0 ) )
       
   501         {
       
   502         streamParam.TRTCP_RR.fractionLost = 0;
       
   503         }
       
   504     else
       
   505         {
       
   506         streamParam.TRTCP_RR.fractionLost = static_cast<TUint8>(
       
   507             ( numPacketsIntervalLost << 8 ) / numPacketsIntervalExpected );
       
   508         }
       
   509 
       
   510     iLastRR_numReceivedPackets = iNumReceivedPackets;
       
   511     iLastRR_numExpectedPackets = numPacketsExpected;
       
   512 
       
   513     streamParam.TRTCP_RR.arrivalJitter = static_cast<TUint32>( iSyncJitter.iJitterTime );
       
   514 
       
   515     // add receiver statistics to sender of SR packet 
       
   516     iRtcpStats.iRtcpReceiverStats.iRoundTripDelay = 0;
       
   517     iRtcpStats.iRtcpReceiverStats.iFractionLost = streamParam.TRTCP_RR.fractionLost;
       
   518     iRtcpStats.iRtcpReceiverStats.iCumNumPacketsLost = streamParam.TRTCP_RR.cumNumPacketsLost;
       
   519     iRtcpStats.iRtcpReceiverStats.iSeqNumReceived = streamParam.TRTCP_RR.seqNumReceived;
       
   520     iRtcpStats.iRtcpReceiverStats.iBandwidth = 0;
       
   521     iRtcpStats.iRtcpReceiverStats.iChannelBufferSize = 0;
       
   522 
       
   523     if ( iSyncJitter.iTimeStampResolution > 0 )
       
   524         {
       
   525         iRtcpStats.iRtcpReceiverStats.iArrivalJitter = ( streamParam.TRTCP_RR.arrivalJitter * KTenthOfmsPerSecond ) /
       
   526                                                       iSyncJitter.iTimeStampResolution;
       
   527         }
       
   528     else
       
   529         {
       
   530         iRtcpStats.iRtcpReceiverStats.iArrivalJitter = 0;
       
   531         }
       
   532 
       
   533     iRtcpStats.iRtcpReceiverStats.iSSRC = streamParam.TRTCP_RR.SSRC; // SSRC sender (coming source)
       
   534     
       
   535     
       
   536     RTP_DEBUG_STAT( "----- RX: Create RTCP Report Statistics -----" );
       
   537     RTP_DEBUG_STAT_DVALUE( "RX: roundTripDelay = ", iRtcpStats.iRtcpReceiverStats.iRoundTripDelay );
       
   538     RTP_DEBUG_STAT_DVALUE( "RX: fractionLost = ", (TInt)iRtcpStats.iRtcpReceiverStats.iFractionLost );
       
   539     RTP_DEBUG_STAT_DVALUE( "RX: cumNumPacketsLost = ", iRtcpStats.iRtcpReceiverStats.iCumNumPacketsLost );
       
   540     RTP_DEBUG_STAT_DVALUE( "RX: seqNumReceived = ", iRtcpStats.iRtcpReceiverStats.iSeqNumReceived );
       
   541     RTP_DEBUG_STAT_DVALUE( "RX: bandwidth = ", iRtcpStats.iRtcpReceiverStats.iBandwidth );
       
   542     RTP_DEBUG_STAT_DVALUE( "RX: channelBufferSize = ", iRtcpStats.iRtcpReceiverStats.iChannelBufferSize );
       
   543     RTP_DEBUG_STAT_DVALUE( "RX: arrivalJitter = ", iRtcpStats.iRtcpReceiverStats.iArrivalJitter );
       
   544     RTP_DEBUG_STAT_DVALUE( "RX: SSRC (Tx) = ", iRtcpStats.iRtcpReceiverStats.iSSRC );
       
   545 
       
   546     TUint32 gtTime = TRtpUtil::GtGetTime();
       
   547     // lastSRTimeStamp: use the middle 32 bits of the 64-bit NTP timestamp
       
   548     // This results in value where the 16-MSB is the amount of seconds, and
       
   549     // the 16-LSB is the fraction of seconds (in tenths of milliseconds).
       
   550     // See RFC3550 page 34 for details.
       
   551     inParam.TRTCP_RR.lastSRTimeStamp = ( iSyncInfo.iNTPTimeStampSec << 16 ) + ( iSyncInfo.iNTPTimeStampFrac >> 16 );
       
   552     inParam.TRTCP_RR.delaySinceLSR = 
       
   553         ( static_cast<TUint32>( ( gtTime - iSyncInfo.iLastUpdateLocalTime ) / KTenthOfmsPerSecond ) << 16 );
       
   554     inParam.TRTCP_RR.delaySinceLSR += 
       
   555     ( ( ( ( TUint32 ) ( ( gtTime - iSyncInfo.iLastUpdateLocalTime ) % KTenthOfmsPerSecond ) ) << 16 ) / KTenthOfmsPerSecond );
       
   556 
       
   557     // For receiving stream, it only generates RR packet. 
       
   558     aPkt->SetType( ERTCP_RR );
       
   559     aPkt->RtpPacketBuild( &streamParam, &inParam );
       
   560     }
       
   561 
       
   562 
       
   563 // ---------------------------------------------------------------------------
       
   564 // TRtpRtcpEnum CRtpRecvStream::RtpStreamProcessRtcpReportSectionL()
       
   565 // For receiving stream, it only process SR packet
       
   566 // ---------------------------------------------------------------------------
       
   567 //
       
   568 TRtpRtcpEnum CRtpRecvStream::RtpStreamProcessRtcpReportSectionL( CRtpPacket* aPkt )
       
   569     {
       
   570     TRtpPacketStreamParam streamParam;
       
   571     TRtpPacketIOParam extractParam;
       
   572     TRtpRtcpEnum parseResult = ERTCP_NO_ERROR;
       
   573     TUint32 gtTime = TRtpUtil::GtGetTime();
       
   574 
       
   575     parseResult = aPkt->RtpPacketProcessL( &streamParam, &extractParam );
       
   576     if ( parseResult < 0 )
       
   577         {
       
   578         return ERTCP_PACKET_ERROR; 
       
   579         }
       
   580 
       
   581     // For receiving stream, it only processes SR packet.
       
   582     if ( aPkt->Type() == ERTCP_SR )
       
   583         {
       
   584         // give this information to receiver on RTCP callback
       
   585         iSyncInfo.iLastUpdateLocalTime = gtTime;
       
   586         iSyncInfo.iNTPTimeStampSec = extractParam.TRTCP_SR.NTPTimeStampSec;
       
   587         iSyncInfo.iNTPTimeStampFrac = extractParam.TRTCP_SR.NTPTimeStampFrac;
       
   588         iSyncInfo.iTimeStamp = extractParam.TRTCP_SR.timeStamp;
       
   589         
       
   590         // do something with numPacketsSent and cumNumOctetsSent 
       
   591         iRtcpStats.iRtcpSenderStats.iSSRC = streamParam.TRTCP_SR.SSRC;
       
   592         iRtcpStats.iRtcpSenderStats.iCumNumOctetsSent = streamParam.TRTCP_SR.cumNumOctetsSent;
       
   593         iRtcpStats.iRtcpSenderStats.iNumPacketsSent = streamParam.TRTCP_SR.numPacketsSent;
       
   594         iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec = iSyncInfo.iNTPTimeStampSec;
       
   595         iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac = iSyncInfo.iNTPTimeStampFrac;
       
   596         iRtcpStats.iRtcpSenderStats.iTimeStamp = iSyncInfo.iTimeStamp;
       
   597         
       
   598         
       
   599         RTP_DEBUG_STAT( "----- RX: Process RTCP Report Statistics -----" );
       
   600         RTP_DEBUG_STAT_DVALUE( "RX: cumNumOctetsSent = ", iRtcpStats.iRtcpSenderStats.iCumNumOctetsSent );
       
   601         RTP_DEBUG_STAT_DVALUE( "RX: numPacketsSent = ", iRtcpStats.iRtcpSenderStats.iNumPacketsSent );
       
   602         RTP_DEBUG_STAT_DVALUE( "RX: SSRC (Tx) = ", iRtcpStats.iRtcpSenderStats.iSSRC );
       
   603         RTP_DEBUG_STAT_DVALUE( "RX: NTPTimeStampSec = ", iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec );
       
   604         RTP_DEBUG_STAT_DVALUE( "RX: NTPTimeStampFrac = ", iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac );
       
   605         RTP_DEBUG_STAT_DVALUE( "RX: timeStamp = ", iRtcpStats.iRtcpSenderStats.iTimeStamp );
       
   606    
       
   607         
       
   608         TTimeStamps timeStamps;
       
   609         timeStamps.iNTPTimeStampFrac = iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac;
       
   610         timeStamps.iNTPTimeStampSec = iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec;
       
   611         timeStamps.iTimeStamp = iRtcpStats.iRtcpSenderStats.iTimeStamp;
       
   612 
       
   613         if ( iRtcpObserver )
       
   614             {
       
   615             iRtcpObserver->SrReceived( iStreamId, iRtcpStats.iRtcpSenderStats.iSSRC, timeStamps );
       
   616             }
       
   617         }
       
   618     else
       
   619         {
       
   620         // the received report can not be associated with the stream 
       
   621         return ERTCP_PACKET_ERROR;
       
   622         }
       
   623 
       
   624     return parseResult;
       
   625     }
       
   626 
       
   627 // ---------------------------------------------------------------------------
       
   628 // TInt CRtpRecvStream::GetRemoteStreamInfo()
       
   629 // 
       
   630 // ---------------------------------------------------------------------------
       
   631 //
       
   632 TInt CRtpRecvStream::GetRemoteStreamInfo( TRtpSdesParams& aSdes )
       
   633     {
       
   634     iRemoteSDES->GetSDES( aSdes );
       
   635     return KErrNone;
       
   636     }
       
   637 
       
   638 // ---------------------------------------------------------------------------
       
   639 // TInt CRtpRecvStream::SetReceivedRTPPackets()
       
   640 // 
       
   641 // ---------------------------------------------------------------------------
       
   642 //
       
   643 void CRtpRecvStream::SetReceivedRTPPackets( TBool aFlag )
       
   644     {
       
   645     iFlagReceivedRTPPackets = aFlag;
       
   646     };
       
   647 
       
   648 
       
   649 // ---------------------------------------------------------------------------
       
   650 // TInt CRtpRecvStream::ReceivedRTPPackets()
       
   651 // 
       
   652 // ---------------------------------------------------------------------------
       
   653 //
       
   654 TBool CRtpRecvStream::ReceivedRTPPackets() const
       
   655     {
       
   656     return iFlagReceivedRTPPackets;
       
   657     };
       
   658 
       
   659 // ---------------------------------------------------------------------------
       
   660 // TInt CRtpRecvStream::GetRemoteSSRC()
       
   661 // 
       
   662 // ---------------------------------------------------------------------------
       
   663 //
       
   664 TRtpSSRC CRtpRecvStream::GetRemoteSSRC()
       
   665     {
       
   666     return iRemoteSSRC;
       
   667     }
       
   668 
       
   669