rtcputil.cpp
Upload User: dangjiwu
Upload Date: 2013-07-19
Package Size: 42019k
Code Size: 21k
Category:

Symbian

Development Platform:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: rtcputil.cpp,v 1.8.28.1 2004/07/09 02:04:33 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxtypes.h"
  50. #include "hxcom.h"
  51. #include "hlxclib/string.h"
  52. #include "rtpwrap.h"
  53. #include "hxtick.h"
  54. #include "hxengin.h"
  55. #include "tconverter.h"
  56. #include "interval.h"
  57. #include "ntptime.h"
  58. #include "rtcputil.h"
  59. #include "hxheap.h"
  60. #ifdef _DEBUG
  61. #undef HX_THIS_FILE
  62. static const char HX_THIS_FILE[] = __FILE__;
  63. #endif
  64. //#define DUMP_REPORTS
  65. //#define DUMP_RECEIVE_REPORTS
  66. //#define DUMP_MEMBER_COUNT
  67. /* Used in UpdateSeqNo */
  68. const UINT32 MAX_DROPOUT = 3000;
  69. const UINT32 MAX_MISORDER = 100;
  70. const UINT32 MIN_SEQUENTIAL = 2;
  71. const UINT32 RTP_SEQ_MOD = (1 << 16);
  72. //ReportHandler::ReportHandler(BOOL bIsSender, BOOL bIsReceiver, UINT32 ulSsrc, UINT32 ulDefaultProbation)
  73. ReportHandler::ReportHandler(BOOL bIsSender, BOOL bIsReceiver, UINT32 ulSsrc)
  74.     : m_pSenderMe(NULL)
  75.     , m_ulMySsrc(ulSsrc)
  76.     , m_pReceiverMe(NULL)
  77. //    , m_ulDefaultProbation(ulDefaultProbation)
  78.     , m_ulAvgRTCPSize(128)
  79.     , m_bInitialIntervalCalc(TRUE)
  80. , m_pNTPBase(NULL)
  81. , m_nRTPTSBase(0)
  82. , m_pTSConverter(NULL)
  83. {
  84.     /* it is "either or" in RealSystem */
  85.     HX_ASSERT((bIsSender || bIsReceiver) && !(bIsSender && bIsReceiver));
  86.     if (bIsSender)
  87.     {
  88. m_pSenderMe = new MyselfAsSender();
  89. m_pSenderMe->m_ulSsrc = ulSsrc;
  90.     }
  91.     else
  92.     {
  93. m_pReceiverMe = new MyselfAsReceiver();
  94. m_pReceiverMe->m_ulSsrc = ulSsrc;;
  95.     }
  96. }
  97. ReportHandler::~ReportHandler()
  98. {       
  99.     CHXMapLongToObj::Iterator i;
  100.     for (i = m_mapReceivers.Begin(); i != m_mapReceivers.End(); ++i)
  101.     {
  102. delete (ReceiverInfo*)(*i);
  103.     }     
  104.     for (i = m_mapSenders.Begin(); i != m_mapSenders.End(); ++i)
  105.     {
  106. delete (ReceptionInfo*)(*i);
  107.     }
  108.     HX_DELETE(m_pSenderMe);
  109.     HX_DELETE(m_pReceiverMe);
  110.     HX_DELETE(m_pNTPBase);
  111.     HX_DELETE(m_pTSConverter);
  112. }
  113. void    
  114. ReportHandler::Init(REF(Timeval) tvInitial, 
  115.     INT64 nInitialRTP,
  116.     CHXTimestampConverter* pConverter)
  117. {
  118.     HX_ASSERT(!m_pNTPBase && "Are you sure to reset this?");
  119.     HX_DELETE(m_pNTPBase);
  120.     HX_DELETE(m_pTSConverter);
  121.     m_pNTPBase = new NTPTime(tvInitial);    
  122.     m_nRTPTSBase = nInitialRTP;
  123.     if (pConverter)
  124.     {
  125. m_pTSConverter = new CHXTimestampConverter();
  126. *m_pTSConverter = *pConverter;
  127.     }
  128. }
  129. void
  130. ReportHandler::OnRTPReceive(UINT32 ulSsrc, UINT16 unSeqNo, 
  131.     UINT32 ulHXTimestamp, UINT32 ulNow)
  132. {
  133.     HX_ASSERT(m_pReceiverMe && !m_pSenderMe);
  134.     
  135.     ReceptionInfo* pRInfo = GetOrCreateReceptionInfo(ulSsrc); 
  136.     pRInfo->m_bHeardSinceLastTime = TRUE;
  137.     // in the same unit
  138.     INT32 lTransit = ulNow - ulHXTimestamp;
  139.     if (0 == pRInfo->m_ulNumPktReceived)
  140.     {
  141. pRInfo->InitSeqNo(unSeqNo);
  142. /* so it won't be some crazy number */
  143. pRInfo->m_ulTransit = lTransit;
  144.     }
  145.     // all updates will be done here.
  146.     pRInfo->UpdateSeqNo(unSeqNo);
  147.     /************************
  148.     * calculate jitter (rfc 1889 Appendix A.8)
  149.     * this doesn't belong to UpdateSeqNo() so just do it here...
  150.     */    
  151.     INT32 lDiff = lTransit - pRInfo->m_ulTransit;
  152.     pRInfo->m_ulTransit = lTransit;
  153.     if (lDiff < 0)
  154.     {
  155. lDiff = -lDiff;
  156.     }
  157.     pRInfo->m_ulJitter += lDiff - ((pRInfo->m_ulJitter + 8) >> 4);
  158. }
  159. void 
  160. ReportHandler::OnRTCPReceive(RTCPPacket* pPkt, UINT32 ulNow)
  161. {
  162.     HX_ASSERT(m_pSenderMe || m_pReceiverMe);
  163. #ifdef DUMP_RECEIVE_REPORTS    
  164.     printf("n%u", pPkt->packet_type);
  165. #endif
  166.     if (RTCP_SR == pPkt->packet_type)
  167.     {
  168. HX_ASSERT(m_pReceiverMe);
  169. // it IS possible to get RTCP before RTP if this is multicast.
  170. ReceptionInfo* pRInfo = GetOrCreateReceptionInfo(pPkt->sr_ssrc);
  171. // the middle 32 bits out of 64 in the NTP timestamp
  172. pRInfo->m_ulLSR = pPkt->ntp_sec  << 16;
  173. pRInfo->m_ulLSR |= (pPkt->ntp_frac >> 16);
  174. pRInfo->m_ulLastSRReceived = ulNow;
  175. pRInfo->m_bHeardSinceLastTime = TRUE;
  176. #ifdef DUMP_RECEIVE_REPORTS
  177.      printf("tSR %u:n", pPkt->sr_ssrc);
  178.      printf("ttrtp_ts:  %un", pPkt->rtp_ts);
  179.      printf("ttntp: %u: %un", pPkt->ntp_sec, pPkt->ntp_frac);
  180.      printf("ttpsent: %u osent: %un", pPkt->psent, pPkt->osent);
  181.      fflush(stdout);
  182. #endif    
  183.     } 
  184.     else if (RTCP_RR == pPkt->packet_type)
  185.     {
  186. // just need to keep track of them.  Ignore the returned value...
  187. GetOrCreateReceiverInfo(pPkt->rr_ssrc);
  188. #ifdef DUMP_RECEIVE_REPORTS
  189. printf("tRR %un", pPkt->rr_ssrc);
  190. for (UINT32 i = 0; i < pPkt->count; i++)
  191. {
  192.     ReceptionReport rr = pPkt->rr_data[i];
  193.          printf("ttssrc: %un", rr.ssrc);
  194.          printf("ttlast_seq: %un", rr.last_seq);
  195.          printf("ttlost: %un", rr.lost);
  196.          printf("ttfraction: %un", rr.fraction);
  197.          printf("ttjitter: %un", rr.jitter);
  198.          printf("ttlsr: %un", rr.lsr);
  199.          printf("ttdlsr: %un", rr.dlsr);
  200. }         
  201.      fflush(stdout);
  202. #endif    
  203.     }
  204.     else if (RTCP_BYE == pPkt->packet_type)
  205.     {
  206. UINT32 ulSsrc;
  207. for (UINT32 i = 0; i < pPkt->count; i++)
  208. {
  209.     ulSsrc = *(pPkt->bye_src + i);
  210.     // remove this entry
  211.     DeleteReceiverInfo(ulSsrc);
  212.     DeleteReceptionInfo(ulSsrc);
  213. }     
  214.     }
  215. #ifdef DUMP_RECEIVE_REPORTS
  216.     else if (RTCP_SDES == pPkt->packet_type)
  217.     {
  218. printf("tSDESn");
  219. SDESItem* pItem = NULL;
  220. CHXSimpleList* pSdesList = NULL;
  221. CHXSimpleList::Iterator j;
  222.      CHXMapLongToObj::Iterator i;
  223.      for (i = pPkt->m_mapSDESSources.Begin(); i != pPkt->m_mapSDESSources.End(); ++i)
  224.      {
  225.          pSdesList = (CHXSimpleList*)(*i);
  226.          for (j = pSdesList->Begin(); j != pSdesList->End(); ++j)
  227.          {
  228.      pItem = (SDESItem*)(*j);
  229.      printf("tttype %u: %sn", pItem->sdes_type, pItem->data);
  230.          }
  231.      }     
  232.     }
  233.     printf("n");    
  234.     fflush(stdout);
  235. #endif    
  236. }
  237. HX_RESULT
  238. ReportHandler::MakeSR(RTCPPacket* pPkt, UINT32 ulNow)
  239. {
  240.     Timeval tvNow((INT32)(ulNow / 1000), (INT32)(ulNow % 1000 * 1000));
  241.     return MakeSR(pPkt, tvNow);    
  242. }
  243. HX_RESULT
  244. ReportHandler::MakeSR(RTCPPacket* pPkt, REF(Timeval) tvNow)
  245. {
  246.     HX_ASSERT(m_pSenderMe);
  247.     HX_ASSERT(pPkt);    
  248.     if (!m_pSenderMe->m_bWeSent)
  249.     {
  250. // no pkt has been sent, wait!
  251. return HXR_UNEXPECTED;
  252.     }
  253.     pPkt->version_flag = 0x02;
  254.     pPkt->padding_flag = 0;    
  255.     pPkt->packet_type = RTCP_SR;
  256.     pPkt->sr_ssrc = m_pSenderMe->m_ulSsrc;
  257.     pPkt->psent = m_pSenderMe->m_ulNumPktSentSoFar;
  258.     pPkt->osent = m_pSenderMe->m_ulNumByteSentSoFar;
  259.     /* since a sender is never a receiver */
  260.     pPkt->count = 0;
  261.     pPkt->sr_data = NULL;
  262.     pPkt->length = 6;
  263.     /* NTP time when this report is generated */
  264.     NTPTime ntpNow(tvNow);
  265.     /*
  266.      * RTP TS that corresponds to NTP time above  
  267.      * m_pNTPBase and m_nRTPTSBase are the same time in diff unit
  268.      */
  269.     INT64 nRTPNow = m_nRTPTSBase;
  270.     if (m_pTSConverter)
  271.     {
  272. nRTPNow += m_pTSConverter->hxa2rtp((UINT32)(ntpNow - *m_pNTPBase));
  273.     }
  274.     else
  275.     {
  276. nRTPNow += (UINT32)(ntpNow - *m_pNTPBase);
  277.     }
  278.     HX_ASSERT(nRTPNow >= 0);
  279.     // NTP
  280.     pPkt->ntp_sec  = ntpNow.m_ulSecond;
  281.     pPkt->ntp_frac = ntpNow.m_ulFraction;
  282.     // RTP
  283.     pPkt->rtp_ts   = INT64_TO_UINT32(nRTPNow);
  284. #ifdef DUMP_REPORTS
  285.     printf("SR %u:n", pPkt->sr_ssrc);
  286.     printf("trtp_ts:  %un", pPkt->rtp_ts);
  287.     printf("tntp: %u: %un", pPkt->ntp_sec, pPkt->ntp_frac);
  288.     printf("tpsent: %u osent: %un", pPkt->psent, pPkt->osent);
  289.     fflush(stdout);
  290. #endif    
  291.     return HXR_OK;
  292. }
  293. /*
  294. *   Make RR.  We need this even if there is no reception report
  295. */
  296. HX_RESULT 
  297. ReportHandler::MakeRR(RTCPPacket* pPkt, UINT32 ulNow)
  298. {
  299. //    Timeval tvNow((INT32)(ulNow / 1000), (INT32)(ulNow % 1000 * 1000));
  300. //    return MakeRR(pPkt, tvNow);        
  301.     HX_ASSERT(m_pReceiverMe); 
  302.     HX_ASSERT(pPkt);    
  303.     pPkt->version_flag = 0x02;
  304.     pPkt->padding_flag = 0;    
  305.     pPkt->packet_type = RTCP_RR;
  306.     pPkt->rr_ssrc = m_pReceiverMe->m_ulSsrc;
  307.     // can't be more than this
  308.     ReceptionReport* pRr = new ReceptionReport[m_mapSenders.GetCount()];
  309.     if (!pRr)
  310.     {
  311. return HXR_OUTOFMEMORY;
  312.     }
  313. #ifdef DUMP_REPORTS
  314.     printf("RR %u:n", pPkt->rr_ssrc);
  315. #endif
  316.     UINT8   chRRCount = 0;
  317.     ReceptionInfo* pRInfo = NULL;
  318.     CHXMapLongToObj::Iterator i;
  319.     for (i = m_mapSenders.Begin(); i != m_mapSenders.End(); ++i)
  320.     {
  321. pRInfo = (ReceptionInfo*)(*i);
  322. if (pRInfo->m_bHeardSinceLastTime)
  323. {
  324.     // need to make a report for this sender
  325.     pRInfo->MakeReceptionReport(i.get_key(), pRr[chRRCount++], ulNow);
  326.     pRInfo->m_bHeardSinceLastTime = FALSE;
  327. }
  328.     }         
  329.     pPkt->count = chRRCount;
  330.     pPkt->length = 1 + 6 * (UINT16)pPkt->count;
  331.     pPkt->SetReceiverReport(pRr, pPkt->count);
  332.     // SetReceiverReport is making a copy.
  333.     HX_VECTOR_DELETE(pRr);
  334.     
  335.     return HXR_OK;
  336. }
  337. /*
  338. *   CNAME is the only one required
  339. */
  340. HX_RESULT
  341. ReportHandler::MakeSDES(RTCPPacket* pPkt, const BYTE* pcCNAME)
  342. {
  343.     HX_ASSERT(m_pSenderMe || m_pReceiverMe);
  344.     HX_ASSERT(pPkt);
  345.     HX_ASSERT(pcCNAME);
  346.     
  347.     pPkt->version_flag = 0x02;
  348.     pPkt->padding_flag = 0;    
  349.     pPkt->packet_type = RTCP_SDES;
  350.     pPkt->count = 1;
  351.     
  352.     UINT16 unByteCount = 0;
  353.     
  354.     SDESItem item;
  355.     item.sdes_type = SDES_CNAME;
  356.     item.length = strlen((const char*)pcCNAME);
  357.     item.data = (BYTE*)pcCNAME;
  358.     if (m_pSenderMe)
  359.     {
  360. pPkt->AddSDESItem(m_pSenderMe->m_ulSsrc, item);
  361.     }
  362.     else
  363.     {
  364. pPkt->AddSDESItem(m_pReceiverMe->m_ulSsrc, item);
  365.     }
  366.     // 2 for sdes_type and length
  367.     unByteCount += item.length + 2;
  368.     /*
  369.      * Increment item byte count for null termination
  370.      */
  371.     unByteCount++;
  372.     
  373.     // Align on word boundary
  374.     // RTCP pkt length is in 32-bits word!
  375.     unByteCount += (unByteCount % 4) ? 4 - (unByteCount % 4) : 0;
  376.     HX_ASSERT(unByteCount % 4 == 0);
  377.     // I am counting 32-bits word
  378.     pPkt->length = (unByteCount / 4);     // count of words - 1
  379.     //one more 32-bits for SSRC
  380.     pPkt->length++;
  381.         
  382.     return HXR_OK;
  383. }
  384. HX_RESULT
  385. ReportHandler::MakeBye(RTCPPacket* pPkt)
  386. {
  387.     HX_ASSERT(m_pSenderMe || m_pReceiverMe);
  388.     HX_ASSERT(pPkt);
  389.     
  390.     pPkt->version_flag = 0x02;
  391.     pPkt->padding_flag = 0;    
  392.     pPkt->packet_type = RTCP_BYE;    
  393.     pPkt->length = 1;   // len in 32-bits words minus one
  394.     pPkt->count = 1;
  395.     // use access function
  396.     if (m_pSenderMe)
  397.     {
  398. pPkt->SetByeSrc(&m_pSenderMe->m_ulSsrc, pPkt->count);        
  399. #ifdef DUMP_REPORTS
  400. printf("BYE %u:n", m_pSenderMe->m_ulSsrc);
  401. #endif
  402.     }
  403.     else
  404.     {
  405.      pPkt->SetByeSrc(&m_pReceiverMe->m_ulSsrc, pPkt->count);        
  406. #ifdef DUMP_REPORTS
  407. printf("BYE %un", m_pReceiverMe->m_ulSsrc);
  408. #endif
  409.     }
  410. #ifdef DUMP_REPORTS
  411.     fflush(stdout);
  412. #endif    
  413.     return HXR_OK;
  414. }
  415. /*
  416. *   for now this is the only APP.  
  417. */
  418. HX_RESULT
  419. ReportHandler::MakeEOSApp(RTCPPacket* pPkt)
  420. {
  421.     HX_ASSERT(m_pSenderMe);
  422.     HX_ASSERT(pPkt);
  423.     
  424.     pPkt->version_flag = 0x02;
  425.     pPkt->padding_flag = 0;    
  426.     pPkt->packet_type = RTCP_APP;
  427.     pPkt->app_ssrc = m_pSenderMe->m_ulSsrc;
  428.     pPkt->count = 1;
  429.     pPkt->length = 4;   // 2 + the length of APPItem...fortunately, we don't 
  430. // have to align them
  431.     memcpy(pPkt->app_name, "RNWK", 4); /* Flawfinder: ignore */
  432.     // this is application dependent...
  433.     APPItem item;
  434.     item.app_type = APP_EOS;
  435.     item.seq_no = m_pSenderMe->m_unLastSeqNo;
  436.     item.packet_sent = (UINT8)m_pSenderMe->m_ulNumPktSentSoFar ? 1 : 0;
  437.     item.timestamp = m_pSenderMe->m_ulLastRTPTimestamp;
  438.     pPkt->SetAPPItem(&item, pPkt->count);   
  439.     return HXR_OK;
  440. }
  441. HX_RESULT
  442. ReportHandler::MakeBufInfoApp(RTCPPacket* pPkt, 
  443.       UINT32 ulLowTS, UINT32 ulHighTS,
  444.       UINT32 ulBytesBuffered)
  445. {
  446.     HX_RESULT res = HXR_UNEXPECTED;
  447.     if (pPkt)
  448.     {
  449. pPkt->version_flag = 0x02;
  450. pPkt->padding_flag = 0;    
  451. pPkt->packet_type = RTCP_APP;
  452. pPkt->count = 1;
  453. pPkt->app_ssrc = m_pReceiverMe->m_ulSsrc;
  454. memcpy(pPkt->app_name, "HELX", 4);
  455. pPkt->length = 2;
  456. APPItem item;
  457. item.app_type = APP_BUFINFO;
  458. item.lowest_timestamp = ulLowTS;
  459. item.highest_timestamp = ulHighTS;
  460. item.bytes_buffered = ulBytesBuffered;
  461. item.padding0 = 0;
  462. pPkt->SetAPPItem(&item, 1);
  463. pPkt->length += 4;
  464. res = HXR_OK;
  465.     }
  466.     return res;
  467. }
  468. ReceiverInfo*
  469. ReportHandler::GetOrCreateReceiverInfo(UINT32 ulSsrc)
  470. {
  471.     ReceiverInfo* pReceiver = NULL;
  472.     if (!m_mapReceivers.Lookup(ulSsrc, (void*&)pReceiver))
  473.     {
  474. #ifdef DUMP_MEMBER_COUNT    
  475. printf("New Receiver (#%u): %un", m_mapReceivers.GetCount()+1, ulSsrc);
  476. fflush(stdout);
  477. #endif
  478. // doesn't exist, create one.
  479. pReceiver = new ReceiverInfo;
  480. if (!pReceiver)
  481. {
  482.     return NULL;
  483. }
  484. m_mapReceivers.SetAt(ulSsrc, (void*)pReceiver);
  485. #if _DEBUG
  486. ReceiverInfo* pTmp = NULL;
  487. HX_ASSERT(m_mapReceivers.Lookup(ulSsrc, (void*&)pTmp));
  488. HX_ASSERT(pTmp);
  489. #endif
  490.     }
  491.     HX_ASSERT(pReceiver);
  492.     return pReceiver;
  493. }
  494. void
  495. ReportHandler::DeleteReceiverInfo(UINT32 ulSsrc)
  496. {
  497.     /* since we need to do timeout, we might as well do the right thing for
  498.     * this as well....mark as delete, and delete after a fixed timeout...so, 
  499.     * we know we don't receive any late pkt after we delete this entry...    
  500.     */
  501.     ReceiverInfo* pReceiver = NULL;
  502.     if (m_mapReceivers.Lookup(ulSsrc, (void*&)pReceiver))
  503.     {
  504. #ifdef DUMP_MEMBER_COUNT    
  505. printf("Deleteing Receiver: %un", ulSsrc);
  506. fflush(stdout);
  507. #endif
  508. HX_ASSERT(pReceiver);
  509. m_mapReceivers.RemoveKey(ulSsrc);
  510. delete pReceiver;
  511.     }    
  512. }
  513. ReceptionInfo*
  514. ReportHandler::GetOrCreateReceptionInfo(UINT32 ulSsrc)
  515. {
  516.     ReceptionInfo* pRInfo = NULL;
  517.     if (!m_mapSenders.Lookup(ulSsrc, (void*&)pRInfo))
  518.     {
  519. #ifdef DUMP_MEMBER_COUNT    
  520. printf("New Sender (#%u): %un", m_mapSenders.GetCount()+1, ulSsrc);
  521. fflush(stdout);
  522. #endif
  523. // doesn't exist, create one.
  524. pRInfo = new ReceptionInfo();
  525. if (!pRInfo)
  526. {
  527.     return NULL;
  528. }
  529. // pRInfo->m_ulProbation = m_ulDefaultProbation;
  530. m_mapSenders.SetAt(ulSsrc, (void*)pRInfo);
  531. #if _DEBUG
  532. ReceptionInfo* pTmp = NULL;
  533. HX_ASSERT(m_mapSenders.Lookup(ulSsrc, (void*&)pTmp));
  534. HX_ASSERT(pTmp);
  535. #endif
  536.     }
  537.     HX_ASSERT(pRInfo);
  538.     return pRInfo;
  539. }
  540. void
  541. ReportHandler::DeleteReceptionInfo(UINT32 ulSsrc)
  542. {
  543.     /* since we need to do timeout, we might as well do the right thing for
  544.     * this as well....mark as delete, and delete after a fixed timeout...so, 
  545.     * we know we don't receive any late pkt after we delete this entry...    
  546.     */
  547.     ReceptionInfo* pRInfo= NULL;
  548.     if (m_mapSenders.Lookup(ulSsrc, (void*&)pRInfo))
  549.     {
  550. #ifdef DUMP_MEMBER_COUNT    
  551. printf("Deleteing Sender: %un", ulSsrc);
  552. fflush(stdout);
  553. #endif     
  554. HX_ASSERT(pRInfo);
  555. m_mapSenders.RemoveKey(ulSsrc);
  556. delete pRInfo;
  557.     }    
  558. }
  559. /*
  560. */
  561. double
  562. ReportHandler::GetRTCPInterval()
  563. {
  564.     // include myself
  565.     double interval = 
  566.     rtcp_interval(m_mapReceivers.GetCount() + 1,
  567.   m_pSenderMe ? m_mapSenders.GetCount()+1 : m_mapSenders.GetCount(),
  568.   m_ulRSByteRate,
  569.   m_ulRRByteRate,
  570.   m_pSenderMe ? m_pSenderMe->m_bWeSent : 0,
  571.   m_ulAvgRTCPSize,
  572.   m_bInitialIntervalCalc,
  573.   m_minRTCPInterval);
  574.     m_bInitialIntervalCalc = FALSE;
  575.     return interval;
  576. }
  577. void ReportHandler::SetRTCPIntervalParams(UINT32 ulRSBitRate, 
  578.   UINT32 ulRRBitRate,
  579.   UINT32 ulMinRTCPIntervalMs)
  580. {
  581.     m_ulRSByteRate = ulRSBitRate >> 3; // bitrate -> byterate
  582.     m_ulRRByteRate = ulRRBitRate >> 3; // bitrate -> byterate
  583.     m_minRTCPInterval = ((double)ulMinRTCPIntervalMs) / 1000.0; // ms -> sec
  584. }
  585. /*
  586. *   ReceptionInfo Func's
  587. */
  588. void
  589. ReceptionInfo::InitSeqNo(UINT16 unSeqNo)
  590. {
  591. #ifdef _DEBUG
  592.     HX_ASSERT(INIT == m_state);
  593.     m_state = UPDATE;
  594. #endif    
  595. //    m_ulBaseSeqNo = unSeqNo - 1;
  596.     m_ulBaseSeqNo = unSeqNo;
  597.     m_unMaxSeqNo =  unSeqNo;
  598.     m_ulBadSeqNo =  RTP_SEQ_MOD + 1;
  599.     m_ulCycles =    0;
  600.     m_ulNumPktReceived = 0;    
  601.     m_ulExpectedPrior  = 0;
  602.     m_ulReceivedPrior  = 0;        
  603. }
  604. BOOL
  605. ReceptionInfo::UpdateSeqNo(UINT16 unSeqNo)
  606. {   
  607. #ifdef _DEBUG
  608.     HX_ASSERT(UPDATE == m_state);
  609. #endif
  610.     UINT16 unDelta = unSeqNo - m_unMaxSeqNo;
  611. #if 0 /* don't ever throu pkt away! */
  612.     if (m_ulProbation)
  613.     {
  614. if (unSeqNo == m_unMaxSeqNo + 1)
  615. {
  616.     // pkt is in sequence
  617.     m_ulProbation--;
  618.     m_unMaxSeqNo = unSeqNo;
  619.     if (0 == m_ulProbation)
  620.     {
  621. InitSeqNo(unSeqNo);
  622. m_ulNumPktReceived++;
  623. return TRUE;
  624.     }
  625. }
  626. else
  627.     // pkt is NOT in sequence
  628.     m_ulProbation = MIN_SEQUENTIAL - 1;
  629.     m_unMaxSeqNo = unSeqNo;
  630. }
  631. return FALSE;
  632.     }
  633.     else 
  634. #endif    
  635.     if (unDelta < MAX_DROPOUT)
  636.     {
  637. // in order, with permissible gap
  638. if (unSeqNo < m_unMaxSeqNo)
  639. {
  640.     // seq# wrapped - count another 64k cycle
  641.     m_ulCycles += RTP_SEQ_MOD;     
  642. }
  643. m_unMaxSeqNo = unSeqNo;
  644.     }
  645.     else if (unDelta <= RTP_SEQ_MOD - MAX_MISORDER)
  646.     {
  647. // seq# made a very large jump
  648. if (unSeqNo == m_ulBadSeqNo)
  649. {
  650.     // two sequential pkts -- assume that the other side
  651.     // restarted w/o telling us, so just re-sync
  652.     // (i.e., pretned this was the first pkt)
  653.     InitSeqNo(unSeqNo);
  654. }
  655. else
  656. {
  657.     
  658.     m_ulBadSeqNo = (unSeqNo + 1) & (RTP_SEQ_MOD - 1);
  659.     // (i.e. m_ulBadSeq = unSeq + 1;)
  660.     return FALSE;
  661. }
  662.     }
  663.     else 
  664.     {
  665. /* duplicate or reordered packet */
  666.     }
  667.     m_ulNumPktReceived++;    
  668.     return TRUE;
  669. }
  670. void
  671. ReceptionInfo::MakeReceptionReport(UINT32 ulSsrc, REF(ReceptionReport) rr, UINT32 ulNow)
  672. {
  673. #ifdef DUMP_REPROTS
  674.     printf("making rr for %un", ulSsrc);
  675.     fflush(stdout);
  676. #endif    
  677.     // ssrc of a sender that we are reporting
  678.     rr.ssrc = ulSsrc;
  679.     
  680.     /* extended last seqno received */
  681.     rr.last_seq = m_ulCycles + m_unMaxSeqNo; 
  682.     /* simply #pkt expected - received */
  683.     UINT32 ulExpected = rr.last_seq - m_ulBaseSeqNo + 1;
  684.     rr.lost =  ulExpected - m_ulNumPktReceived; 
  685.     UINT32 ulExpectedInterval = ulExpected - m_ulExpectedPrior;
  686.     UINT32 ulReceivedInterval = m_ulNumPktReceived - m_ulReceivedPrior;
  687.     INT32  lLostInterval = ulExpectedInterval - ulReceivedInterval;
  688.     // save them for the next time
  689.     m_ulExpectedPrior = ulExpected;
  690.     m_ulReceivedPrior = m_ulNumPktReceived;
  691.     /*
  692.      * The resulting fraction is an 8-bit fixed point number with the binary
  693.      * point at the left edge.
  694.      */  
  695.     if (0 == ulExpectedInterval || lLostInterval <= 0)
  696.     {
  697. rr.fraction = 0;
  698.     }
  699.     else
  700.     {
  701. rr.fraction = (UINT8)((lLostInterval << 8) / ulExpectedInterval);
  702.     }
  703.     
  704.     rr.jitter = m_ulJitter >> 4;
  705.     rr.lsr = m_ulLSR ? m_ulLSR : 0;
  706.     /* expressed in 1/65536 sec...ahhh...make it 66 */
  707.     rr.dlsr = (m_ulLastSRReceived ? 
  708. CALCULATE_ELAPSED_TICKS(m_ulLastSRReceived, ulNow) : 
  709. 0 /* SR not yet received */) * 66;
  710. #ifdef DUMP_REPROTS
  711.     printf("tssrc: %un", rr.ssrc);
  712.     printf("tlast_seq: %un", rr.last_seq);
  713.     printf("tlost: %un", rr.lost);
  714.     printf("tfraction: %un", rr.fraction);
  715.     printf("tjitter: %un", rr.jitter);
  716.     printf("tlsr: %un", rr.lsr);
  717.     printf("tdlsr: %un", rr.dlsr);
  718.     fflush(stdout);
  719. #endif    
  720. }