rtp/rtpstack/src/rtptranstream.cpp
changeset 0 307788aac0a8
child 19 b5e99d8877c7
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 "rtptranstream.h"
       
    22 
       
    23 // ---------------------------------------------------------------------------
       
    24 // C++ default constructor can NOT contain any code, that
       
    25 // might leave.
       
    26 // ---------------------------------------------------------------------------
       
    27 //
       
    28 CRtpTranStream::CRtpTranStream( const TRtpPayloadType aPayloadType,
       
    29                                 const TRtpId aSessionId,
       
    30                                 const TRtpId aStreamId,
       
    31                                 const TRtpSSRC aSSRC,
       
    32                                 MRtcpObserver* aRtcpObserver,
       
    33                                 const TUint32* aProfileRTPTimeRates )
       
    34     :
       
    35     CRtpStream( aStreamId,
       
    36                 aSessionId,
       
    37                 aProfileRTPTimeRates,
       
    38                 aRtcpObserver,
       
    39                 aPayloadType ),
       
    40     iFlagSentRTPPackets( EFalse ),
       
    41     iPreviousTime( 0 ),
       
    42     iPreviousRemoteSN( 0 ),
       
    43     iPrevRemoteTime( 0 ),
       
    44     iCumNumOctetsSent( 0 ),
       
    45     iCumNumOctetsReceived( 0 ),
       
    46     iCumNumOctetsSent_last( 0 ),
       
    47     iFSentRtcpReport( EFalse )
       
    48     {
       
    49     iLocalSSRC = aSSRC;
       
    50     iTimeStamp = 0;
       
    51     iSeqNumCycles = 0;
       
    52 
       
    53     for ( TUint i = 0; i < KSNMaxArray; i++ )
       
    54         {
       
    55         iSN_size[i] = 0;
       
    56         }
       
    57     // If the client application does not specify sequence numbers, we
       
    58     // randomize the first one.
       
    59     TTime tmp_time;
       
    60     tmp_time.HomeTime();
       
    61     TInt64 seed = tmp_time.Int64();
       
    62     iBaseSeqNum = static_cast<TRtpSequence>( TRtpUtil::Random( seed )
       
    63                                              & 0xFFFF ); // Use 16-LSB only
       
    64     iSeqNum = iBaseSeqNum;
       
    65     }
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // Symbian 2nd phase constructor can leave.
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 void CRtpTranStream::ConstructL()
       
    72     {
       
    73     }
       
    74 
       
    75 
       
    76 // ---------------------------------------------------------------------------
       
    77 // Two-phased constructor.
       
    78 // ---------------------------------------------------------------------------
       
    79 //
       
    80 CRtpTranStream* CRtpTranStream::NewL( const TRtpPayloadType aPayloadType,
       
    81                                       const TRtpId aSessionId,
       
    82                                       const TRtpId aTranStreamId,
       
    83                                       const TRtpSSRC aSSRC,
       
    84                                       MRtcpObserver* aRtcpObserver,
       
    85                                       const TUint32* aProfileRTPTimeRates )
       
    86     {
       
    87     CRtpTranStream* self =
       
    88         new ( ELeave ) CRtpTranStream( aPayloadType,
       
    89                                        aSessionId,
       
    90                                        aTranStreamId,
       
    91                                        aSSRC,
       
    92                                        aRtcpObserver,
       
    93                                        aProfileRTPTimeRates );
       
    94     CleanupStack::PushL( self );
       
    95     self->ConstructL();
       
    96     CleanupStack::Pop(); // self 
       
    97     return self;
       
    98     }
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // Destructor
       
   102 // ---------------------------------------------------------------------------
       
   103 //
       
   104 CRtpTranStream::~CRtpTranStream()
       
   105     {
       
   106     }
       
   107 
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // TInt CRtpTranStream::ResetStreamStat()
       
   111 // 
       
   112 // ---------------------------------------------------------------------------
       
   113 //
       
   114 TInt CRtpTranStream::ResetStreamStat()
       
   115     {
       
   116     TRtcpStats rtcpStat;
       
   117 
       
   118     RtcpStats( rtcpStat );
       
   119     
       
   120     rtcpStat.iRtcpSenderStats.iNumPacketsSent = 0;
       
   121     rtcpStat.iRtcpSenderStats.iCumNumOctetsSent = 0;
       
   122     rtcpStat.iRtcpSenderStats.iNTPTimeStampSec = 0;    // NTP seconds
       
   123     rtcpStat.iRtcpSenderStats.iNTPTimeStampFrac = 0;   // NTPfraction
       
   124     rtcpStat.iRtcpSenderStats.iTimeStamp = 0; 
       
   125 
       
   126     // The receiver stats are updated when receiving RR packets, so reset
       
   127     rtcpStat.iRtcpReceiverStats.iChannelBufferSize = 0;
       
   128     rtcpStat.iRtcpReceiverStats.iRoundTripDelay = 0;
       
   129     rtcpStat.iRtcpReceiverStats.iFractionLost = 0; 
       
   130     rtcpStat.iRtcpReceiverStats.iCumNumPacketsLost = 0;
       
   131     rtcpStat.iRtcpReceiverStats.iSeqNumReceived = 0;
       
   132     rtcpStat.iRtcpReceiverStats.iSSRC = 0;
       
   133 
       
   134     iRtcpStats = rtcpStat;
       
   135     
       
   136     iFlagSentRTPPackets = EFalse;
       
   137     iFSentRtcpReport = EFalse;
       
   138 
       
   139     iCumNumOctetsSent = 0;
       
   140     iCumNumOctetsSent_last = 0;
       
   141     iPreviousTime = 0;
       
   142     iPreviousRemoteSN = 0;
       
   143     iSeqNumCycles = 0;
       
   144 
       
   145     for ( TUint i = 0; i < KSNMaxArray; i++ )
       
   146         {
       
   147         iSN_size[i] = 0;
       
   148         }
       
   149         
       
   150     return KErrNone;
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // TInt CRtpTranStream::GetStreamStat()
       
   155 // 
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 TInt CRtpTranStream::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 = rtcpStat.iRtcpSenderStats.iNTPTimeStampSec;
       
   175     aStat.iNTPTimeStampFrac = rtcpStat.iRtcpSenderStats.iNTPTimeStampFrac;
       
   176     aStat.iTimeStamp = rtcpStat.iRtcpSenderStats.iTimeStamp;
       
   177 
       
   178     return KErrNone;
       
   179     }
       
   180 
       
   181 // ---------------------------------------------------------------------------
       
   182 // TInt CRtpTranStream::BuildRtpPacket()
       
   183 // 
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 TInt CRtpTranStream::BuildRtpPacket( const TRtpSendHeader& aHeaderInfo,
       
   187                                      const TDesC8& aPayloadData,
       
   188                                      TRtpSequence aSeqNum,
       
   189                                      TBool aSetSeqNum,
       
   190                                      CRtpPacket* aPktSnd )
       
   191     {
       
   192     TRtpPacketStreamParam streamParam;
       
   193     TRtpPacketIOParam inParam;
       
   194 
       
   195     if ( FirstPkg() )
       
   196         {
       
   197         RtpStreamSyncInit( aHeaderInfo.iTimestamp );
       
   198         SetFirstPkg( EFalse );
       
   199         }
       
   200 
       
   201     //
       
   202     // The interpretation of the marker is defined by a profile.
       
   203     // It is used for marking significant events such as frame boundaries or
       
   204     // talkspurts in the packet stream.
       
   205 
       
   206     // Timestamp
       
   207     // -- random initial value
       
   208     // -- monotonically increasing 
       
   209     // -- increases by one sampling period for fixed-rate audio
       
   210     // -- increases for every sample independent of whether the block is
       
   211     //    transmitted or dropped as silent.
       
   212     // -- used for playout and inter-media synchronization.
       
   213     //
       
   214 
       
   215     //
       
   216     // construct RTP packet
       
   217     //
       
   218 
       
   219     inParam.TRTP.padding = aHeaderInfo.iPadding;
       
   220 
       
   221     if ( aHeaderInfo.iHeaderExtension )
       
   222         {
       
   223         inParam.TRTP.fHeaderExtension = 1;
       
   224         inParam.TRTP.extension.type = aHeaderInfo.iHeaderExtension->iType;
       
   225         inParam.TRTP.extension.length = aHeaderInfo.iHeaderExtension->iLength;
       
   226         inParam.TRTP.extension.data = aHeaderInfo.iHeaderExtension->iData;
       
   227         }
       
   228     else
       
   229         {
       
   230         inParam.TRTP.extension.data = NULL;
       
   231         }
       
   232 
       
   233     inParam.TRTP.marker = aHeaderInfo.iMarker; 
       
   234 
       
   235     inParam.TRTP.payloadData = const_cast<TUint8*>( aPayloadData.Ptr() );
       
   236     inParam.TRTP.payloadDataLen = aPayloadData.Length();
       
   237 
       
   238     streamParam.TRTP.payload = aHeaderInfo.iPayloadType;
       
   239 
       
   240     if ( aSetSeqNum )
       
   241         {
       
   242         iSeqNum = aSeqNum;
       
   243         }
       
   244     streamParam.TRTP.seqNum = iSeqNum;
       
   245 
       
   246     streamParam.TRTP.SSRC = iLocalSSRC;
       
   247     streamParam.TRTP.timeStamp = aHeaderInfo.iTimestamp;
       
   248     
       
   249     //
       
   250     // build and send the packet
       
   251     //
       
   252     aPktSnd->RtpPacketBuild( &streamParam, &inParam ); 
       
   253 
       
   254     
       
   255     RTP_DEBUG_DETAIL_DVALUE( "CRtpTranStream::BuildRtpPacket, Stream ID = ",
       
   256                   iStreamId );
       
   257     RTP_DEBUG_DETAIL_DVALUE( "CRtpTranStream::BuildRtpPacket, SSRC = ",
       
   258                   streamParam.TRTP.SSRC );
       
   259     RTP_DEBUG_DETAIL_DVALUE( "CRtpTranStream::BuildRtpPacket, Seq Num = ",
       
   260                   static_cast<TInt>( streamParam.TRTP.seqNum ) );
       
   261     RTP_DEBUG_DETAIL_DVALUE( "CRtpTranStream::BuildRtpPacket, Time Stamp = ",
       
   262                   aHeaderInfo.iTimestamp );
       
   263     
       
   264     
       
   265     // update sent octets and remote bandwidth parameters 
       
   266     IncCumNumOctetsSent( aPayloadData.Length() );
       
   267 
       
   268     // update stream parameters
       
   269     iTimeStamp = aHeaderInfo.iTimestamp;
       
   270     iSeqNum++;
       
   271     if ( iSeqNum == 0 )
       
   272         {
       
   273         iSeqNumCycles++;
       
   274         }
       
   275 
       
   276     SetSentRTPPackets( ETrue );
       
   277 
       
   278     return KErrNone;
       
   279     }
       
   280 
       
   281 // ---------------------------------------------------------------------------
       
   282 // TInt CRtpTranStream::BuildRtcpBYEPacket()
       
   283 // 
       
   284 // ---------------------------------------------------------------------------
       
   285 //
       
   286 TInt CRtpTranStream::BuildRtcpBYEPacket( const TDesC8& aReason,
       
   287                                          CRtpPacket* aPktRtcpSnd )
       
   288     {
       
   289     TInt paddingSize = 0;
       
   290     TRtpPacketStreamParam streamParam;
       
   291     TRtpPacketIOParam initParam;
       
   292     TInt ret = KErrNone;
       
   293 
       
   294     TInt byeSize = aReason.Size();
       
   295 
       
   296     // build RTCP BYE packet header
       
   297     TInt sourceCount = 1; 
       
   298     TInt length = 0;
       
   299 
       
   300     initParam.TRTCP_HEADER.pt = ERTCP_BYE;
       
   301 
       
   302     if ( ( 1 + byeSize ) % 4 == 0 )
       
   303         {
       
   304         // multiples of 4 bytes, no padding is needed
       
   305         // calculate total number of 32 bit words in SDES packet
       
   306         length = ( 1 + byeSize ) / 4 + 1;   
       
   307         }
       
   308     else
       
   309         {
       
   310         // not multiples of 4 bytes, padding is needed
       
   311         paddingSize = 4 - ( 1 + byeSize ) % 4;
       
   312         length = ( 1 + byeSize ) / 4 + 2;
       
   313         }
       
   314 
       
   315     initParam.TRTCP_HEADER.sourceCount = sourceCount;
       
   316     initParam.TRTCP_HEADER.length = length;
       
   317     aPktRtcpSnd->SetType( ERTCP_HEADER );
       
   318 
       
   319     aPktRtcpSnd->RtpPacketBuild( &streamParam, &initParam );
       
   320 
       
   321     streamParam.TRTCP_BYE.SSRC = iLocalSSRC;
       
   322 
       
   323     initParam.TRTCP_BYE.reason = ( TUint8 * ) aReason.Ptr();
       
   324     initParam.TRTCP_BYE.reasonSize = byeSize;
       
   325     initParam.TRTCP_BYE.paddingSize = paddingSize;
       
   326 
       
   327     aPktRtcpSnd->SetType( ERTCP_BYE );
       
   328     aPktRtcpSnd->RtpPacketBuild( &streamParam, &initParam ); 
       
   329     
       
   330 
       
   331     RTCP_DEBUG_DETAIL_DVALUE( "SEND: Send BYE Packet TX Stream ID = ",
       
   332               iStreamId );
       
   333     RTCP_DEBUG_DETAIL_DVALUE( "SEND: Send BYE Packet SSRC = ",
       
   334               iLocalSSRC );
       
   335     RTCP_DEBUG_DETAIL( "SEND: Sending RTCP BYE message as" );
       
   336     RTCP_DEBUG_DETAIL( initParam.TRTCP_BYE.reason );
       
   337 
       
   338     return ret;
       
   339     }
       
   340 
       
   341 // ---------------------------------------------------------------------------
       
   342 // TInt CRtpTranStream::BuildRtcpAPPPacket()
       
   343 // 
       
   344 // ---------------------------------------------------------------------------
       
   345 //
       
   346 TInt CRtpTranStream::BuildRtcpAPPPacket( const TRtcpApp& aApp,
       
   347                                          CRtpPacket* aPktRtcpSnd )
       
   348     {
       
   349     TRtpPacketStreamParam streamParam;
       
   350     TRtpPacketIOParam initParam;
       
   351 
       
   352     initParam.TRTCP_HEADER.pt = ERTCP_APP;
       
   353 
       
   354     initParam.TRTCP_HEADER.sourceCount = aApp.iSubType;
       
   355 
       
   356     initParam.TRTCP_HEADER.length = aApp.iAppDataLen / 4 + 3 - 1;
       
   357 
       
   358     aPktRtcpSnd->SetType( ERTCP_HEADER );
       
   359 
       
   360     aPktRtcpSnd->RtpPacketBuild( &streamParam, &initParam );
       
   361 
       
   362     streamParam.TRTCP_APP.SSRC = iLocalSSRC;
       
   363 
       
   364     Mem::Copy( initParam.TRTCP_APP.name, aApp.iName, 4 );
       
   365     initParam.TRTCP_APP.appData = const_cast<TUint8*>( aApp.iAppData );
       
   366     initParam.TRTCP_APP.appDataLen = aApp.iAppDataLen;
       
   367 
       
   368     aPktRtcpSnd->SetType( ERTCP_APP );
       
   369 
       
   370     aPktRtcpSnd->RtpPacketBuild( &streamParam, &initParam ) ; 
       
   371 
       
   372     RTP_DEBUG_DETAIL_DVALUE( "SEND: Send APP Packet TX Stream ID = ", iStreamId );
       
   373     RTP_DEBUG_DETAIL_DVALUE( "SEND: Send APP Packet SSRC = " , iLocalSSRC );
       
   374     RTCP_DEBUG_DETAIL( "SEND: Sending RTCP APP packet as " );
       
   375     RTCP_DEBUG_DETAIL( "InitParam.TRTCP_APP.appData " );
       
   376 
       
   377     return KErrNone;
       
   378     }
       
   379 
       
   380 // ---------------------------------------------------------------------------
       
   381 // CRtpTranStream::RtpStreamSyncInit()
       
   382 // For transmission stream, iSyncInfo is initialized by the
       
   383 // first packet sent.
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 void CRtpTranStream::RtpStreamSyncInit( TRtpTimeStamp aInitTimeStamp )
       
   387     {
       
   388     TUint32 gtTime = TRtpUtil::GtGetTime();
       
   389 
       
   390     TTime time1;
       
   391     TTime time2;
       
   392     TTimeIntervalSeconds interval;
       
   393     time1.HomeTime();
       
   394     _LIT( KTime, "19700101:000000.000000" );
       
   395     time2.Set( KTime ); // microsecond from Jan. 1 1970
       
   396     time1.SecondsFrom( time2, interval );
       
   397 
       
   398     iSyncInfo.iNTPTimeStampSec = interval.Int() + KGetTimeOfDayToNTPOffset;
       
   399 
       
   400 
       
   401     iSyncInfo.iNTPTimeStampFrac = static_cast<TUint32>(
       
   402         ( ( ( ( TUint32 ) ( gtTime % KTenthOfmsPerSecond ) ) << 16 )
       
   403         / KTenthOfmsPerSecond ) << 16 );
       
   404 
       
   405     iSyncInfo.iTimeStamp = aInitTimeStamp;
       
   406     iSyncInfo.iLastUpdateLocalTime = gtTime;
       
   407     }
       
   408 
       
   409 // ---------------------------------------------------------------------------
       
   410 // CRtpTranStream::RtpStreamSyncCurrent()
       
   411 // iSyncInfo : NTP timestamp of initialization as a reference
       
   412 //             to update the current NTP timestamp
       
   413 // aSyncInfoCurrent : Bring back current NTP Time stamp
       
   414 // ---------------------------------------------------------------------------
       
   415 //
       
   416 void CRtpTranStream::RtpStreamSyncCurrent( TRtpTimeSync* aSyncInfoCurrent )
       
   417     {
       
   418     if ( !aSyncInfoCurrent )
       
   419         {
       
   420         return;
       
   421         }
       
   422     TUint32 gtTime = TRtpUtil::GtGetTime();
       
   423     TUint32 diffFraction = ( gtTime - iSyncInfo.iLastUpdateLocalTime )
       
   424                            % KTenthOfmsPerSecond;
       
   425 
       
   426     aSyncInfoCurrent->iNTPTimeStampSec = iSyncInfo.iNTPTimeStampSec +
       
   427           static_cast<TUint32>( gtTime - iSyncInfo.iLastUpdateLocalTime )
       
   428           / KTenthOfmsPerSecond;
       
   429     aSyncInfoCurrent->iNTPTimeStampFrac = ( static_cast<TUint32>(
       
   430         ( diffFraction << 16 ) / KTenthOfmsPerSecond ) << 16 );
       
   431     }
       
   432 
       
   433 // ---------------------------------------------------------------------------
       
   434 // CRtpTranStream::RtpStreamCreateRtcpReportSection()
       
   435 // For transmission stream, it only generates SR packet.
       
   436 // ---------------------------------------------------------------------------
       
   437 //
       
   438 void CRtpTranStream::RtpStreamCreateRtcpReportSection( CRtpPacket* aPkt )
       
   439     {
       
   440     TRtpPacketStreamParam streamParam;
       
   441     TRtpPacketIOParam inParam;
       
   442 
       
   443     TRtpTimeSync syncInfoCurrent;
       
   444 
       
   445     streamParam.TRTCP_SR.SSRC = iLocalSSRC;
       
   446 
       
   447     streamParam.TRTCP_SR.numPacketsSent = iSeqNum + ( iSeqNumCycles << 16 )
       
   448                                           - iBaseSeqNum;
       
   449     streamParam.TRTCP_SR.cumNumOctetsSent = iCumNumOctetsSent;
       
   450 
       
   451     iRtcpStats.iRtcpSenderStats.iNumPacketsSent =
       
   452         streamParam.TRTCP_SR.numPacketsSent;
       
   453     iRtcpStats.iRtcpSenderStats.iCumNumOctetsSent =
       
   454         streamParam.TRTCP_SR.cumNumOctetsSent;
       
   455     iRtcpStats.iRtcpSenderStats.iSSRC = streamParam.TRTCP_SR.SSRC;
       
   456 
       
   457     RtpStreamSyncCurrent( &syncInfoCurrent );
       
   458 
       
   459     inParam.TRTCP_SR.NTPTimeStampSec = syncInfoCurrent.iNTPTimeStampSec;
       
   460     inParam.TRTCP_SR.NTPTimeStampFrac = syncInfoCurrent.iNTPTimeStampFrac;
       
   461     inParam.TRTCP_SR.timeStamp = iTimeStamp;
       
   462 
       
   463     iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec =
       
   464         inParam.TRTCP_SR.NTPTimeStampSec;
       
   465     iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac =
       
   466         inParam.TRTCP_SR.NTPTimeStampFrac;
       
   467     iRtcpStats.iRtcpSenderStats.iTimeStamp = inParam.TRTCP_SR.timeStamp;
       
   468     
       
   469 
       
   470     RTP_DEBUG_STAT( "----- TX: Create RTCP Report Statistics -----" );
       
   471     RTP_DEBUG_STAT_DVALUE( "TX: numPacketsSent = ",
       
   472               iRtcpStats.iRtcpSenderStats.iNumPacketsSent );
       
   473     RTP_DEBUG_STAT_DVALUE( "TX: cumNumOctetsSent = ",
       
   474               iRtcpStats.iRtcpSenderStats.iCumNumOctetsSent );
       
   475     RTP_DEBUG_STAT_DVALUE( "TX: SSRC (Tx) = ",
       
   476               iRtcpStats.iRtcpSenderStats.iSSRC );
       
   477     RTP_DEBUG_STAT_DVALUE( "TX: NTPTimeStampSec = ",
       
   478               iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec );
       
   479     RTP_DEBUG_STAT_DVALUE( "TX: NTPTimeStampFrac = ",
       
   480               iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac );
       
   481     RTP_DEBUG_STAT_DVALUE( "TX: timeStamp = ",
       
   482               iRtcpStats.iRtcpSenderStats.iTimeStamp );
       
   483 
       
   484 
       
   485     // For transmission stream, it only generates SR packet.
       
   486     aPkt->SetType( ERTCP_SR );
       
   487     aPkt->RtpPacketBuild( &streamParam, &inParam );
       
   488     }
       
   489 
       
   490 
       
   491 // ---------------------------------------------------------------------------
       
   492 // TRtpRtcpEnum CRtpTranStream::RtpStreamProcessRtcpReportSectionL()
       
   493 // For transmission stream, it only processes RR packet.
       
   494 // ---------------------------------------------------------------------------
       
   495 //
       
   496 TRtpRtcpEnum CRtpTranStream::RtpStreamProcessRtcpReportSectionL(
       
   497                                  CRtpPacket* aPkt )
       
   498     {
       
   499     TRtpPacketStreamParam streamParam;
       
   500     TRtpPacketIOParam extractParam;
       
   501     TRtpRtcpEnum parseResult = ERTCP_NO_ERROR;
       
   502     TUint32 gtTime = TRtpUtil::GtGetTime();
       
   503 
       
   504     parseResult = aPkt->RtpPacketProcessL( &streamParam, &extractParam );
       
   505     if ( parseResult == ERTCP_PACKET_ERROR )
       
   506         {
       
   507         return ERTCP_PACKET_ERROR;
       
   508         }
       
   509 
       
   510     // For transmission stream, it only processes RR packet.
       
   511     if ( aPkt->Type() == ERTCP_RR )
       
   512         {
       
   513         TInt roundTripDelay;
       
   514 
       
   515         roundTripDelay = RtpStreamSyncGetRoundTripDelay(
       
   516                              extractParam.TRTCP_RR.lastSRTimeStamp,
       
   517                              extractParam.TRTCP_RR.delaySinceLSR );
       
   518 
       
   519         iCumNumOctetsReceived += iSN_size[streamParam.TRTCP_RR.seqNumReceived
       
   520                                      % KSNMaxArray] -
       
   521                                  iSN_size[iPreviousRemoteSN % KSNMaxArray];
       
   522 
       
   523         if ( iCumNumOctetsSent > iCumNumOctetsReceived )
       
   524             {
       
   525             iRtcpStats.iRtcpReceiverStats.iChannelBufferSize =
       
   526                 8 * ( iCumNumOctetsSent - iCumNumOctetsReceived );
       
   527             }
       
   528         else
       
   529             {
       
   530             iRtcpStats.iRtcpReceiverStats.iChannelBufferSize = 0;
       
   531             }
       
   532 
       
   533         iRtcpStats.iRtcpReceiverStats.iRoundTripDelay = roundTripDelay;
       
   534         iRtcpStats.iRtcpReceiverStats.iFractionLost =
       
   535             streamParam.TRTCP_RR.fractionLost;
       
   536         iRtcpStats.iRtcpReceiverStats.iCumNumPacketsLost =
       
   537             streamParam.TRTCP_RR.cumNumPacketsLost;
       
   538         iRtcpStats.iRtcpReceiverStats.iSeqNumReceived =
       
   539             streamParam.TRTCP_RR.seqNumReceived;
       
   540 
       
   541         // SSRC coming from the source 
       
   542         iRtcpStats.iRtcpReceiverStats.iSSRC = streamParam.TRTCP_RR.SSRC;
       
   543 
       
   544         EstimateBandWidths( gtTime );
       
   545 
       
   546         // Remember some things for next time we receive an RR
       
   547         iPreviousRemoteSN = streamParam.TRTCP_RR.seqNumReceived;
       
   548         iPrevRemoteTime = gtTime;
       
   549         iPreviousTime = gtTime;
       
   550         iCumNumOctetsSent_last = iCumNumOctetsSent;
       
   551         
       
   552         
       
   553         RTP_DEBUG_STAT( "----- TX: Process RTCP Report Statistics -----" );
       
   554         RTP_DEBUG_STAT_DVALUE( "TX: bandwidth (Tx) = ",
       
   555                   iRtcpStats.iRtcpReceiverStats.iTxBandwidth );
       
   556         RTP_DEBUG_STAT_DVALUE( "TX: roundTripDelay = ",
       
   557                   iRtcpStats.iRtcpReceiverStats.iRoundTripDelay );
       
   558         RTP_DEBUG_STAT_DVALUE( "TX: fractionLost = ",
       
   559                   static_cast<TInt>(
       
   560                       iRtcpStats.iRtcpReceiverStats.iFractionLost ) );
       
   561         RTP_DEBUG_STAT_DVALUE( "TX: cumNumPacketsLost = ",
       
   562                   iRtcpStats.iRtcpReceiverStats.iCumNumPacketsLost );
       
   563         RTP_DEBUG_STAT_DVALUE( "TX: seqNumReceived = ",
       
   564                   iRtcpStats.iRtcpReceiverStats.iSeqNumReceived );
       
   565         RTP_DEBUG_STAT_DVALUE( "TX: SSRC (Rx) = ",
       
   566                   iRtcpStats.iRtcpReceiverStats.iSSRC );
       
   567         
       
   568         
       
   569         if ( iRtcpObserver )
       
   570             {
       
   571             iRtcpObserver->RrReceived( iStreamId,
       
   572                                        iRtcpStats.iRtcpReceiverStats.iSSRC );
       
   573             }
       
   574         }
       
   575 
       
   576     return parseResult;
       
   577     }
       
   578 
       
   579 // ---------------------------------------------------------------------------
       
   580 // TUint32 CRtpTranStream::EstimateBandWidths()
       
   581 // Make an estimate of the Tx and Rx bandwidths.
       
   582 // ---------------------------------------------------------------------------
       
   583 // 
       
   584 void CRtpTranStream::EstimateBandWidths( TUint32 aCurrentTime )
       
   585     {
       
   586     /* NOTE: This is just a simple estimate, which assumes the following:
       
   587      * - this is an end-to-end session
       
   588      * - the sessions and streams are set up before traffic starts
       
   589      * - the payload bitrate is constant
       
   590      * The result of this estimation should not be used in any other contexts.
       
   591      */
       
   592 
       
   593     // Tx bandwidth
       
   594     TReal B_A( 0 );
       
   595 
       
   596     // Rx bandwidth
       
   597     TReal B_B( 0 );
       
   598 
       
   599     // number of received packets between the current and previous RR's
       
   600     TInt N_B( 0 );
       
   601 
       
   602     TReal avgPacketSize( 0 );
       
   603     TUint8 fracLost_i( iRtcpStats.iRtcpReceiverStats.iFractionLost );
       
   604     TUint32 lastRecvd_i( iRtcpStats.iRtcpReceiverStats.iSeqNumReceived ); 
       
   605     TUint32 lastRecvd_k( iPreviousRemoteSN );
       
   606     TUint packetsSent( iRtcpStats.iRtcpSenderStats.iNumPacketsSent ); 
       
   607 
       
   608     TReal timeBetweenRRs = static_cast<TReal>( aCurrentTime - iPreviousTime )
       
   609                            / KTenthOfmsPerSecond;
       
   610 
       
   611     // Continue only if two RR's have been received and numbers are valid
       
   612     if ( iCumNumOctetsSent_last == 0 ||
       
   613          iPreviousRemoteSN == 0 ||
       
   614          iPrevRemoteTime == 0 ||
       
   615          iPreviousTime == 0 ||
       
   616          timeBetweenRRs <= 0 ||
       
   617          packetsSent == 0 ||
       
   618          fracLost_i == 255 /* Would result in divide by zero and B_B = 0 */ )
       
   619         {
       
   620         // If this is the first RR to be received, this returns 0,
       
   621         // otherwise this returns the result of the previous calculation
       
   622         iRtcpStats.iRtcpReceiverStats.iBandwidth = 0;
       
   623         iRtcpStats.iRtcpReceiverStats.iTxBandwidth = 0;
       
   624         return;
       
   625         }
       
   626 
       
   627     B_A = 8 * static_cast<TReal>( ( iCumNumOctetsSent -
       
   628               iCumNumOctetsSent_last ) ) / timeBetweenRRs;
       
   629     iRtcpStats.iRtcpReceiverStats.iTxBandwidth = static_cast<TUint32>( B_A );
       
   630 
       
   631     avgPacketSize = static_cast<TReal>( iCumNumOctetsSent )/ packetsSent;
       
   632 
       
   633     /* The fraction lost is the fractional part of a decimal value between 0 
       
   634      * and 1 (the fixed point is at the left edge of this value. The decimal
       
   635      * equivalent can be computed by dividing by 255. */
       
   636     N_B = static_cast<TInt>( 
       
   637               ( lastRecvd_i - lastRecvd_k ) * ( 1 - ( fracLost_i / 255.0 ) ) );
       
   638 
       
   639     B_B = 8 * ( avgPacketSize * N_B ) / timeBetweenRRs;
       
   640     
       
   641     iRtcpStats.iRtcpReceiverStats.iBandwidth = static_cast<TUint32>( B_B );
       
   642     }
       
   643 
       
   644 // ---------------------------------------------------------------------------
       
   645 // TUint32 CRtpTranStream::RtpStreamSyncGetRoundTripDelay()
       
   646 // It is transmission stream's duty to calculate round trip delay.
       
   647 // ---------------------------------------------------------------------------
       
   648 // 
       
   649 TUint32 CRtpTranStream::RtpStreamSyncGetRoundTripDelay(
       
   650                             TUint32 aLastSRTimeStamp, TUint32 aDelaySinceLSR )
       
   651     {
       
   652     TInt roundTripDelay = 0;
       
   653     TRtpTimeStamp currentNTP;
       
   654     TUint32 gtTime = TRtpUtil::GtGetTime();
       
   655     TUint32 diffFraction = ( gtTime - iSyncInfo.iLastUpdateLocalTime )
       
   656                            % KTenthOfmsPerSecond;
       
   657 
       
   658     if ( aLastSRTimeStamp != 0 )
       
   659         {
       
   660         // calculate current NTP in a 16+16 bit precision
       
   661         // (same format as lastSRTimeStamp)
       
   662         currentNTP = ( ( iSyncInfo.iNTPTimeStampSec +
       
   663                        ( gtTime - iSyncInfo.iLastUpdateLocalTime )
       
   664                        / KTenthOfmsPerSecond ) << 16 );    
       
   665         currentNTP += static_cast<TUint32>( ( diffFraction << 16 )
       
   666                       / KTenthOfmsPerSecond );
       
   667 
       
   668         roundTripDelay = currentNTP - aLastSRTimeStamp - aDelaySinceLSR;
       
   669         if ( roundTripDelay > 0 )
       
   670             {
       
   671             // 16-MSB of roundTripDelay are seconds, 16-LSB of roundTripDelay
       
   672             // is the fraction part. Transform this to a decimal value
       
   673             // representing the round trip delay in tenths of millisecons
       
   674             // ( 10^4 ). See RFC 3550 page 34 for details.
       
   675             roundTripDelay = ( static_cast<TUint32>( roundTripDelay ) >> 16 ) *
       
   676                              KTenthOfmsPerSecond +
       
   677                              ( ( ( roundTripDelay & 0xFFFF ) *
       
   678                                  KTenthOfmsPerSecond ) >> 16 );
       
   679             }
       
   680         else
       
   681             {
       
   682             // here we assume the delay is so small that we cannot get
       
   683             // an accurate reading
       
   684             roundTripDelay = 0;     
       
   685             }
       
   686         }
       
   687 
       
   688     return static_cast<TUint32>( roundTripDelay );
       
   689     }
       
   690 
       
   691 //end of file
       
   692 
       
   693