rtcputil.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:21k
源码类别:

Symbian

开发平台:

C/C++

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