rtptran.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:90k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: rtptran.cpp,v 1.54.2.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. /****************************************************************************
  50.  *  Defines
  51.  */
  52. #define ACCEPTABLE_SYNC_NOISE 3
  53. #define STREAM_END_DELAY_RTP_TOLERANCE 500
  54. /****************************************************************************
  55.  *  Includes
  56.  */
  57. #include "hxtypes.h"
  58. #include "hxassert.h"
  59. #include "debug.h"
  60. #include "hxcom.h"
  61. #include "hxmarsh.h"
  62. #include "hxstrutl.h"
  63. #include "netbyte.h"
  64. #include "hxengin.h"
  65. #include "ihxpckts.h"
  66. #include "hxsbuffer.h"
  67. #include "hxcomm.h"
  68. #include "hxmon.h"
  69. #include "netbyte.h"
  70. #include "hxstring.h"
  71. #include "chxpckts.h"
  72. #include "hxslist.h"
  73. #include "hxmap.h"
  74. #include "hxdeque.h"
  75. #include "hxbitset.h"
  76. #include "timebuff.h"
  77. #include "timeval.h"
  78. #include "tconverter.h"
  79. #include "rtptypes.h"
  80. #include "hxqosinfo.h"
  81. #include "hxqossig.h"
  82. #include "hxqos.h"
  83. //#include "hxcorgui.h"
  84. #include "ntptime.h"
  85. #include "rtspif.h"
  86. #include "rtsptran.h"
  87. #include "rtptran.h"
  88. #include "rtpwrap.h" // Wrappers for PMC generated base classes
  89. #include "basepkt.h"
  90. #include "hxtbuf.h"
  91. #include "transbuf.h"
  92. #include "hxtick.h"
  93. #include "random32.h" // random32()
  94. #include "pkthndlr.h" // in rtpmisc for RTCP routine
  95. #include "rtcputil.h" // takes care of RTCP in RTP mode
  96. #include "rtspmsg.h"
  97. #include "hxprefs.h" // IHXPreferences
  98. #include "hxmime.h"
  99. #include "hxcore.h"
  100. #include "hxheap.h"
  101. #ifdef PAULM_IHXTCPSCAR
  102. #include "objdbg.h"
  103. #endif
  104. #ifdef _DEBUG
  105. #undef HX_THIS_FILE
  106. static const char HX_THIS_FILE[] = __FILE__;
  107. #endif
  108. #include "bufnum.h"
  109. #define MAX_STARTINFO_WAIT_TIME 20000 // in milliseconds
  110. #define MIN_NUM_PACKETS_SCANNED_FOR_LIVE_START    5
  111. #define MAX_NUM_PACKETS_GAPPED_FOR_LIVE_START   1
  112. static const UINT32 NORMAL_ACK_INTERVAL = 1000;        // 1/sec
  113. static const UINT32 MINIMUM_ACK_INTERVAL = 200;        // wait 200msecs
  114. static const UINT32 NORMAL_REPORT_INTERVAL = 5000; // 1 per 5secs
  115. static const UINT32 TRANSPORT_BUF_GROWTH_RATE  = 1000;
  116. static const UINT32 LATENCY_REPORT_INTERVAL_MS = 1000;
  117. static const UINT32 RTP_NAT_TIMEOUT = 15000; // Default timeout period
  118. static UINT32 GetNATTimeout(IUnknown* pContext)
  119. {
  120.     UINT32 ret = RTP_NAT_TIMEOUT;
  121.     IHXPreferences* pPrefs = NULL;
  122.     
  123.     if (pContext &&
  124. (HXR_OK == pContext->QueryInterface(IID_IHXPreferences, 
  125.     (void**)&pPrefs)))
  126.     {
  127. IHXBuffer* pPrefBuf = NULL;
  128. if ((HXR_OK == pPrefs->ReadPref("UDPNATTimeout", pPrefBuf)) &&
  129.     pPrefBuf)
  130. {
  131.     int tmp = atoi((const char*)pPrefBuf->GetBuffer());
  132.     if (tmp >= 0)
  133.     {
  134. ret = (UINT32)tmp;
  135.     }
  136.     HX_RELEASE(pPrefBuf);
  137. }
  138.         HX_RELEASE(pPrefs);
  139.     }
  140.     return ret;
  141. }
  142. /******************************************************************************
  143. *   RTP RTP RTP RTP RTP 
  144. ******************************************************************************/
  145. RTPBaseTransport::RTPBaseTransport(BOOL bIsSource)
  146.     : RTSPTransport(bIsSource)
  147.     , m_lRefCount(0)    
  148.     , m_pBwMgrInput(0)    
  149.     , m_pSyncServer(NULL)
  150.     , m_streamNumber(0)
  151.     , m_uFirstSeqNum(0)
  152.     , m_ulFirstRTPTS(0)
  153.     , m_bFirstSet(FALSE)
  154.     , m_bWeakStartSync(FALSE)
  155.     , m_lTimeOffsetHX(0)
  156.     , m_lTimeOffsetRTP(0)
  157.     , m_lOffsetToMasterHX(0)
  158.     , m_lOffsetToMasterRTP(0)
  159.     , m_lSyncOffsetHX(0)
  160.     , m_lSyncOffsetRTP(0)
  161.     , m_lNTPtoHXOffset(0)
  162.     , m_bNTPtoHXOffsetSet(FALSE)
  163.     , m_ulLastRTPTS(0)
  164.     , m_ulLastHXTS(0)
  165.     , m_ulLastRawRTPTS(0)
  166.     , m_bLastTSSet(FALSE)
  167.     , m_pRTCPTran(0)
  168.     , m_pReportHandler(0)
  169.     , m_ulBaseTS(0)
  170.     , m_bHasMarkerRule(FALSE)
  171.     , m_bHasRTCPRule(FALSE)
  172.     , m_ulPayloadWirePacket(0)
  173.     , m_bIsLive(FALSE)
  174.     , m_ulExtensionSupport(0)
  175.     , m_bSeqNoSet(FALSE)
  176.     , m_bRTPTimeSet(FALSE)
  177.     , m_bActive(TRUE)
  178.     , m_pFirstPlayTime(NULL)
  179.     , m_bWaitForStartInfo(TRUE)
  180.     , m_bAbortWaitForStartInfo(FALSE)
  181.     , m_bEmulatePVSession(FALSE)
  182.     , m_pMBitHandler(NULL)
  183.     , m_pQoSInfo(NULL)
  184.     , m_bSSRCDetermined(FALSE)
  185.     , m_ulSSRCDetermined(0)
  186.     , m_cLSRRead(0)
  187.     , m_cLSRWrite(0)
  188. #ifdef RTP_MESSAGE_DEBUG
  189.     , m_bMessageDebug(FALSE)
  190. #endif // RTP_MESSAGE_DEBUG
  191. {
  192.     m_wrapSequenceNumber = DEFAULT_WRAP_SEQ_NO;
  193. }
  194. RTPBaseTransport::~RTPBaseTransport()
  195. {
  196.     resetStartInfoWaitQueue();
  197. }
  198. STDMETHODIMP
  199. RTPBaseTransport::QueryInterface(REFIID riid, void** ppvObj)
  200. {
  201.     if (IsEqualIID(riid, IID_IUnknown))
  202.     {
  203.         AddRef();
  204.         *ppvObj = this;
  205.         return HXR_OK;
  206.     }
  207.     else if (IsEqualIID(riid, IID_IHXSourceBandwidthInfo))
  208.     {
  209.         AddRef();
  210.         *ppvObj = (IHXSourceBandwidthInfo*)this;
  211.         return HXR_OK;
  212.     }
  213.     *ppvObj = NULL;
  214.     return HXR_NOINTERFACE;
  215. }
  216. STDMETHODIMP_(UINT32)
  217. RTPBaseTransport::AddRef()
  218. {
  219.     return InterlockedIncrement(&m_lRefCount);
  220. }
  221. STDMETHODIMP_(UINT32)
  222. RTPBaseTransport::Release()
  223. {
  224.     if(InterlockedDecrement(&m_lRefCount) > 0)
  225.     {
  226. return m_lRefCount;
  227.     }
  228.     delete this;
  229.     return 0;
  230. }
  231. void
  232. RTPBaseTransport::Done()
  233. {
  234.     HX_RELEASE(m_pQoSInfo);
  235.     HX_RELEASE(m_pBwMgrInput);
  236.     HX_RELEASE(m_pRTCPTran);
  237.     HX_RELEASE(m_pPacketFilter);
  238.     HX_RELEASE(m_pSyncServer);
  239.     HX_DELETE(m_pFirstPlayTime);
  240. }
  241. HX_RESULT
  242. RTPBaseTransport::init()
  243. {
  244.     // m_pReportHandler will be freed in RTCPBaseTransport::Done()...
  245.     HX_ASSERT(!m_pReportHandler);
  246.     m_pReportHandler =   
  247. new ReportHandler(m_bIsSource, !m_bIsSource, random32(HX_GET_TICKCOUNT()));    
  248.     HX_ASSERT(m_pReportHandler);
  249.     if(!m_pReportHandler)
  250.     {
  251.         return HXR_OUTOFMEMORY;
  252.     }
  253.     
  254. #ifdef RTP_MESSAGE_DEBUG
  255.     IHXPreferences* pPreferences = NULL;
  256.     if (m_pContext &&
  257. (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,
  258.      (void**) &pPreferences)))
  259.     {
  260. IHXBuffer* pBuffer = NULL;
  261. if (HXR_OK == pPreferences->ReadPref("RTPMessageDebug", pBuffer))
  262. {
  263.     m_bMessageDebug = atoi((const char*)pBuffer->GetBuffer()) ? TRUE : FALSE;
  264.     HX_RELEASE(pBuffer);
  265.     if (m_bMessageDebug)
  266.     {
  267. if (HXR_OK == pPreferences->ReadPref("RTPMessageDebugFile", pBuffer))
  268. {
  269.     if (pBuffer->GetSize() <= 0)
  270.     {
  271. // no file name, no log
  272. m_bMessageDebug = FALSE;
  273.     }
  274.     else
  275.     {
  276. m_messageDebugFileName = (const char*) pBuffer->GetBuffer();
  277.     }
  278. }
  279.                 HX_RELEASE(pBuffer);
  280.     }
  281. }
  282.     }
  283.     HX_RELEASE(pPreferences);
  284. #endif // RTP_MESSAGE_DEBUG
  285.     return HXR_OK;
  286. }
  287. void
  288. RTPBaseTransport::addStreamInfo(RTSPStreamInfo* pStreamInfo, UINT32 ulBufferDepth)
  289. {   
  290.     RTSPTransport::addStreamInfo(pStreamInfo, ulBufferDepth);
  291.     // there better be only one stream
  292.     m_streamNumber = pStreamInfo->m_streamNumber;
  293.     // if pStreamInfo->m_rtpPayloadType is -1, it hasn't been set
  294.     // by user, so just assign RTP_PAYLOAD_RTSP
  295.     if (pStreamInfo->m_rtpPayloadType < 0)
  296.     {
  297. m_rtpPayloadType = RTP_PAYLOAD_RTSP;
  298.     }
  299.     else
  300.     {
  301. m_rtpPayloadType = (UINT8)pStreamInfo->m_rtpPayloadType;
  302.     }
  303.     if (pStreamInfo)
  304.     {
  305. if (pStreamInfo->m_bHasMarkerRule)
  306. {
  307.     m_bHasMarkerRule = pStreamInfo->m_bHasMarkerRule;
  308.     m_markerRuleNumber = pStreamInfo->m_markerRule;
  309.     // better be odd.
  310.     HX_ASSERT(m_markerRuleNumber & 0x1);
  311. }
  312.      m_bIsLive = pStreamInfo->m_bIsLive;
  313.      m_ulExtensionSupport = pStreamInfo->m_bExtensionSupport;
  314.      m_bActive = pStreamInfo->m_bActive;
  315. m_bIsSyncMaster = pStreamInfo->m_bIsSyncMaster;
  316. // RTP transport always creates RTP packets on reception
  317. if (!m_bIsSource)
  318. {
  319.     RTSPStreamData* pStreamData = NULL;
  320.     pStreamData = m_pStreamHandler->getStreamData(pStreamInfo->m_streamNumber);
  321.     HX_ASSERT(pStreamData);
  322.     if (pStreamData)
  323.     {
  324. pStreamData->m_bUsesRTPPackets = TRUE;
  325.     }
  326.     if (pStreamData->m_pTSConverter)
  327.     {
  328. m_pRTCPTran->SetTSConverter(
  329.     pStreamData->m_pTSConverter->GetConversionFactors());
  330.     }
  331. }
  332.      /*
  333.       *  Reflection support
  334.       */
  335.      m_bHasRTCPRule = pStreamInfo->m_bHasRTCPRule;
  336.      if (m_bHasRTCPRule)
  337.      {
  338.          m_RTCPRuleNumber = pStreamInfo->m_RTCPRule;
  339.      }
  340. m_ulPayloadWirePacket = pStreamInfo->m_ulPayloadWirePacket;
  341. if (m_pRTCPTran)
  342. {
  343.     m_pRTCPTran->addStreamInfo(pStreamInfo, ulBufferDepth);
  344. }
  345.     }
  346. }
  347. /*
  348. *  We need to set an initial SeqNo & timestamp for RTP
  349. */
  350. HX_RESULT
  351. RTPBaseTransport::setFirstSeqNum(UINT16 uStreamNumber, UINT16 uSeqNum)
  352. {
  353.     HX_RESULT theErr = HXR_UNEXPECTED;
  354.     // On client we allow setting of sequence number only once not to cause
  355.     // havoc in transport buffer
  356.     if (m_bIsSource || (!m_bSeqNoSet))
  357.     {
  358. theErr = RTSPTransport::setFirstSeqNum(uStreamNumber, uSeqNum);
  359. #ifdef RTP_MESSAGE_DEBUG
  360. messageFormatDebugFileOut("INIT: StartSeqNum=%u", 
  361.   uSeqNum);
  362. #endif // RTP_MESSAGE_DEBUG
  363. if (SUCCEEDED(theErr))
  364. {
  365.     m_bSeqNoSet = TRUE;
  366. }
  367.     }
  368.     
  369.     return theErr;
  370. }
  371. void
  372. RTPBaseTransport::setFirstTimeStamp(UINT16 uStreamNumber, UINT32 ulTS, 
  373.                                     BOOL bIsRaw)
  374. {
  375.     RTSPStreamData* pStreamData = 
  376. m_pStreamHandler->getStreamData(uStreamNumber);
  377.     if (pStreamData)
  378.     {
  379. if (m_bIsSource)
  380. {     
  381.     /* ulFrom is what we want to put in RTP-Info: rtptimestamp */
  382.     if (pStreamData->m_pTSConverter && !bIsRaw)
  383.     {
  384. pStreamData->m_lastTimestamp = pStreamData->m_pTSConverter->hxa2rtp(ulTS);
  385.     }
  386.     else
  387.     {
  388. pStreamData->m_lastTimestamp = ulTS;
  389.     }
  390. }
  391. else if (!m_bRTPTimeSet)
  392. {
  393.     // ulTS is what's reported in rtptime of RTP-Info PLAY response 
  394.     // header in RTP time.  Unit is RTP.
  395.     /*
  396.      * HXTimeval = PktTime*Factor - (ulTS*Factor - m_ulPlayRangeFrom)
  397.      *  RTPTimeval = PktTime - (ulTS - m_ulPlayRangeFrom / Factor)
  398.      */     
  399.             if (m_ulPlayRangeFrom != RTSP_PLAY_RANGE_BLANK)
  400.             {
  401.         if (pStreamData->m_pTSConverter)
  402.         {
  403.     m_lTimeOffsetRTP = ulTS -
  404.        pStreamData->
  405.     m_pTSConverter->hxa2rtp_raw(m_ulPlayRangeFrom);
  406.     pStreamData->m_pTSConverter->setAnchor(m_ulPlayRangeFrom, ulTS);
  407.     m_lTimeOffsetHX = 0;
  408.         }
  409.         else
  410.         {
  411.     m_lTimeOffsetHX = m_lTimeOffsetRTP = ulTS - m_ulPlayRangeFrom;
  412.         }
  413.             }
  414.     if ((m_ulPlayRangeFrom != RTSP_PLAY_RANGE_BLANK) &&
  415. (m_ulPlayRangeTo != RTSP_PLAY_RANGE_BLANK))
  416.     {
  417. pStreamData->m_pTransportBuffer->InformTimestampRange(
  418.     m_ulPlayRangeFrom,
  419.     m_ulPlayRangeTo,
  420.     STREAM_END_DELAY_RTP_TOLERANCE);
  421.     }
  422. #ifdef RTP_MESSAGE_DEBUG
  423.     messageFormatDebugFileOut("INIT: RTPOffset=%u HXOffset=%u", 
  424.       m_lTimeOffsetRTP, 
  425.       m_lTimeOffsetHX);
  426. #endif // RTP_MESSAGE_DEBUG
  427.     // Reset the time stamp ordering
  428.     HX_DELETE(pStreamData->m_pTSOrderHack);
  429. }
  430. m_bRTPTimeSet = TRUE;
  431.     }
  432. }
  433. void
  434. RTPBaseTransport::notifyEmptyRTPInfo(void)
  435. {
  436.     // If RTP-Info is empty there is no point in waiting for out-of-band
  437.     // start info (start seq number and time stamp) since this is the
  438.     // only out-of-band method of communicating start info. in RTP.
  439.     m_bAbortWaitForStartInfo = TRUE;
  440. }
  441. void 
  442. RTPBaseTransport::setPlayRange(UINT32 ulFrom, UINT32 ulTo)
  443. {
  444.     // this is the Range values in PLAY request in RMA time (ms) called on PLAY 
  445.     // request
  446.     RTSPTransport::setPlayRange(ulFrom, ulTo);
  447.     
  448.     m_bSeqNoSet = FALSE;
  449.     m_bRTPTimeSet = FALSE;
  450.     m_bWaitForStartInfo = TRUE;
  451.     m_bAbortWaitForStartInfo = FALSE;
  452.     m_uFirstSeqNum = 0;
  453.     m_ulFirstRTPTS = 0;
  454.     m_bFirstSet = FALSE;
  455.     m_bWeakStartSync = FALSE;
  456.     m_lTimeOffsetHX = 0;
  457.     m_lTimeOffsetRTP = 0;
  458.     m_lOffsetToMasterHX = 0;
  459.     m_lOffsetToMasterRTP = 0;
  460.     m_lSyncOffsetHX = 0;
  461.     m_lSyncOffsetRTP = 0;
  462.     m_ulLastRTPTS = 0;
  463.     m_ulLastHXTS = 0;
  464.     m_ulLastRawRTPTS = 0;
  465.     m_bLastTSSet = FALSE;
  466.     m_lNTPtoHXOffset = 0;
  467.     m_bNTPtoHXOffsetSet = FALSE;
  468.     resetStartInfoWaitQueue();
  469. #ifdef RTP_MESSAGE_DEBUG
  470.     messageFormatDebugFileOut("INIT: PlayRange=%u-%u", 
  471.        ulFrom, ulTo);
  472. #endif // RTP_MESSAGE_DEBUG
  473. }
  474. HX_RESULT
  475. RTPBaseTransport::setFirstPlayTime(Timeval* pTv)
  476. {
  477.     if (!m_pFirstPlayTime)
  478.     {
  479. m_pFirstPlayTime = new Timeval();
  480.         if(!m_pFirstPlayTime)
  481.         {
  482.             return HXR_OUTOFMEMORY;
  483.         }
  484.     }
  485.     
  486.     m_pFirstPlayTime->tv_sec = pTv->tv_sec;
  487.     m_pFirstPlayTime->tv_usec = pTv->tv_usec;
  488.     return HXR_OK;
  489. }
  490. HX_RESULT
  491. RTPBaseTransport::reflectPacket(BasePacket* pBasePacket, REF(IHXBuffer*)pSendBuf)
  492. {
  493.     HX_ASSERT(pBasePacket);
  494.     HX_ASSERT(m_bHasRTCPRule);
  495.     HX_ASSERT(m_ulPayloadWirePacket==1);
  496.     
  497.     HX_RESULT theErr = HXR_OK;
  498.     
  499.     IHXPacket* pPacket = pBasePacket->GetPacket();
  500.     IHXBuffer* pBuffer = NULL;
  501.     UINT32 ulLen = 0;
  502.     
  503.     /*
  504.      * Sanity check 
  505.      */
  506.     if (!pPacket)
  507.     {
  508. return HXR_UNEXPECTED;
  509.     }
  510.     else if (pPacket->IsLost())
  511.     {
  512. pPacket->Release();
  513. return HXR_IGNORE;
  514.     }
  515.     else
  516.     {
  517. pBuffer = pPacket->GetBuffer();
  518. if (!pBuffer)
  519. {
  520.     pPacket->Release();
  521.     return HXR_UNEXPECTED;
  522. }    
  523.     }
  524.     ulLen = pBuffer->GetSize();
  525.     HX_ASSERT(pPacket->GetStreamNumber() == m_streamNumber);
  526.     HX_ASSERT(pPacket->GetASMFlags());
  527.     /*
  528.      * RTP packet
  529.      */    
  530.     UINT16 streamNumber = pPacket->GetStreamNumber();    
  531.     RTSPStreamData* pStreamData = 
  532. m_pStreamHandler->getStreamData(streamNumber);
  533.     if (isRTCPRule(pPacket->GetASMRuleNumber()))
  534.     {
  535. /*
  536.  *  RTCP packet
  537.  */
  538. if (!pStreamData->m_bFirstPacket)
  539. {
  540.     if (m_reflectorInfo.m_unSeqNoOffset  && m_reflectorInfo.m_ulRTPTSOffset)
  541.     {
  542. theErr = FixRTCPSR(m_pCommonClassFactory,
  543.    pBuffer, 
  544.            pSendBuf,
  545.            m_reflectorInfo.m_ulRTPTSOffset);
  546.     }
  547.     else
  548.     {
  549. theErr = HXR_OK;
  550. pSendBuf = pBuffer;
  551. pSendBuf->AddRef();
  552.     }
  553. }
  554. else
  555. {
  556.     theErr = HXR_IGNORE;
  557. }
  558. BYTE* pReport = pBuffer->GetBuffer();
  559. if ((pReport) && ((*(++pReport)) == 200))
  560. {
  561.     pReport += 7;
  562.     UINT32 ulSourceSec = GetDwordFromBufAndInc(pReport);
  563.     UINT32 ulSourceFract = GetDwordFromBufAndInc(pReport);
  564.     
  565.     HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
  566.     Timeval tvNow((INT32) rmatv.tv_sec, (INT32)rmatv.tv_usec);
  567.     NTPTime ntpNow(tvNow);
  568.     
  569.     m_LSRHistory [m_cLSRWrite].m_ulSourceLSR = ulSourceSec  << 16;
  570.     m_LSRHistory [m_cLSRWrite].m_ulSourceLSR |= (ulSourceFract >> 16); 
  571.     m_LSRHistory [m_cLSRWrite].m_ulServerLSR = ntpNow.m_ulSecond  << 16;
  572.     m_LSRHistory [m_cLSRWrite].m_ulServerLSR |= (ntpNow.m_ulFraction >> 16); 
  573.     (++m_cLSRWrite) %= LSR_HIST_SZ;
  574. }
  575. if (HXR_OK == theErr)
  576. {
  577.     theErr = m_pRTCPTran->reflectRTCP(pSendBuf);
  578.     HX_RELEASE(pSendBuf);
  579. }
  580. pPacket->Release();
  581. pBuffer->Release();
  582. if (HXR_OK == theErr)
  583. {
  584.     return HXR_IGNORE;
  585. }
  586. else
  587. {
  588.     return theErr;
  589. }     
  590.     }
  591.     if (!pStreamData->m_packetSent)
  592.     {
  593. pStreamData->m_packetSent = TRUE;
  594.     }
  595.     
  596.     if (pStreamData->m_bFirstPacket)
  597.     {
  598. pStreamData->m_bFirstPacket = FALSE;
  599. BYTE* pcOrig = pBuffer->GetBuffer();
  600. UINT16 unFirstSeqNo = 0;
  601. UINT32 ulFirstRTPTS = 0;
  602. pcOrig += 2;
  603. unFirstSeqNo = *pcOrig++<<8; 
  604. unFirstSeqNo |= *pcOrig++;
  605.         ulFirstRTPTS = GetDwordFromBufAndInc(pcOrig);
  606. if (m_pReportHandler)
  607. {
  608.     m_pReportHandler->SetSSRC(GetDwordFromBufAndInc(pcOrig));
  609. }
  610.         // get an offset for reflector
  611. UINT16 nA = m_reflectorInfo.m_unSeqNoOffset ;
  612. UINT16 nB = unFirstSeqNo;
  613. UINT32 lA = m_reflectorInfo.m_ulRTPTSOffset;
  614. UINT32 lB = ulFirstRTPTS;
  615. m_reflectorInfo.m_unSeqNoOffset = 0 - unFirstSeqNo;
  616. m_reflectorInfo.m_ulRTPTSOffset = 0 - ulFirstRTPTS;
  617.     }
  618.     if (m_reflectorInfo.m_unSeqNoOffset  && m_reflectorInfo.m_ulRTPTSOffset)
  619.     {
  620.      theErr = FixRTPHeader(m_pCommonClassFactory,
  621.       pBuffer, 
  622.             pSendBuf,
  623.             m_reflectorInfo.m_unSeqNoOffset ,
  624.                  m_reflectorInfo.m_ulRTPTSOffset);
  625.     }
  626.     else
  627.     {
  628. theErr = HXR_OK;
  629. pSendBuf = pBuffer;
  630. pSendBuf->AddRef();
  631.     }
  632.     // forever increasing
  633.     pStreamData->m_seqNo = pBasePacket->m_uSequenceNumber;
  634.     pStreamData->m_lastTimestamp = pPacket->GetTime();
  635.     HX_ASSERT(pBuffer);
  636.     BYTE* pRawPkt = (BYTE*)pBuffer->GetBuffer();
  637.     UINT32 ulPayloadLen = ulLen;
  638.     UINT32 ulRTPHeaderSize = 0;
  639.     UINT8 uiCSRCCount = (UINT32)(pRawPkt[0] & 0x0F);
  640. // We only want to count the payload, not the RTP headers.
  641.     ulRTPHeaderSize += (4 * 3); // RTP fixed header size, not including CSRCs.
  642.     ulRTPHeaderSize += 4 * uiCSRCCount; // CSRCs. 
  643. // Extension header present.
  644.     if (pRawPkt[0] & 0x20)
  645.     {
  646.         HX_ASSERT(ulPayloadLen - ulRTPHeaderSize > 0);
  647.         ulRTPHeaderSize += 2; // 16-bit profile-defined field
  648.     // Overrun prevention.
  649.         if (pBuffer->GetSize() > ulRTPHeaderSize + 1)
  650.         {
  651.             // Extension length is last 16 bits of first word.
  652.             UINT32 ulExtensionLength = (pRawPkt[ulRTPHeaderSize] << 8) + pRawPkt[ulRTPHeaderSize + 1];
  653.             ulRTPHeaderSize += 2; // 16-bit length field.
  654.             ulRTPHeaderSize += (ulExtensionLength * 4); // Rest of extension header.
  655.         }
  656.     }
  657.     
  658.     ulPayloadLen -= ulRTPHeaderSize;
  659.     updateQoSInfo(ulPayloadLen);
  660.     /*
  661.      * clean up
  662.      */
  663.     pPacket->Release();
  664.     pBuffer->Release();
  665.     return theErr;
  666. }
  667. void
  668. RTPBaseTransport::updateQoSInfo(UINT32 ulBytesSent)
  669. {
  670.     m_ulPacketsSent++;    
  671.     m_lBytesSent += ulBytesSent;
  672.     if (!m_pQoSInfo)
  673.     {
  674.         return;
  675.     }
  676.     UINT64 ulSessionBytesSent = m_pQoSInfo->GetBytesSent();
  677.     ulSessionBytesSent += ulBytesSent;
  678.     m_pQoSInfo->SetBytesSent(ulSessionBytesSent);
  679.     UINT32 ulSessionPacketsSent = m_pQoSInfo->GetPacketsSent();
  680.     ulSessionPacketsSent++;
  681.     m_pQoSInfo->SetPacketsSent(ulSessionPacketsSent);
  682. }
  683. UINT32
  684. RTPBaseTransport::MapLSR(UINT32 ulSourceLSR)
  685. {
  686.     if (m_ulPayloadWirePacket == 0)
  687.     {
  688. return ulSourceLSR;
  689.     }
  690.     UINT8  cSearchCursor = m_cLSRRead;
  691.     while (cSearchCursor != m_cLSRWrite)
  692.     {
  693. if (m_LSRHistory [cSearchCursor].m_ulSourceLSR == ulSourceLSR)
  694. {
  695.     m_cLSRRead = cSearchCursor;
  696.     return m_LSRHistory [cSearchCursor].m_ulServerLSR;
  697. }
  698. (++cSearchCursor) %= LSR_HIST_SZ;
  699.     }
  700.     return 0;
  701. }
  702. HX_RESULT
  703. FixRTPHeader(IHXCommonClassFactory* pCCF, 
  704.      IHXBuffer* pOrigBuf, 
  705.      REF(IHXBuffer*) pNewBuf, 
  706.      UINT16 unSeqNoOffset, 
  707.      UINT32 ulRTPTSOffset)
  708. {      
  709.     if (pOrigBuf->GetSize() < 8)
  710.     {
  711. return HXR_INVALID_PARAMETER;
  712.     }
  713.     
  714.     HX_RESULT theErr = pCCF->CreateInstance(IID_IHXBuffer, (void**) &pNewBuf);
  715.     if (HXR_OK == theErr)
  716.     {
  717. theErr = pNewBuf->Set(pOrigBuf->GetBuffer(), pOrigBuf->GetSize());
  718.     }
  719.     if (HXR_OK == theErr)
  720.     {
  721. BYTE* pcOrig = pOrigBuf->GetBuffer();
  722. UINT16 unSeqNo = 0;
  723. UINT32 ulRTPTS = 0;
  724. pcOrig += 2;
  725. unSeqNo = *pcOrig++<<8; 
  726. unSeqNo |= *pcOrig++;
  727. ulRTPTS = GetDwordFromBufAndInc(pcOrig);
  728.         
  729.         UINT16 nA = unSeqNo;
  730. UINT32 lA = ulRTPTS;
  731. // update
  732. unSeqNo += unSeqNoOffset;
  733. ulRTPTS += ulRTPTSOffset;
  734. BYTE* pc = pNewBuf->GetBuffer();
  735. pc += 2;
  736. *pc++ = (UINT8)(unSeqNo>>8); 
  737. *pc++ = (UINT8)(unSeqNo);
  738. *pc++ = (UINT8)(ulRTPTS>>24); 
  739. *pc++ = (UINT8)(ulRTPTS>>16); 
  740. *pc++ = (UINT8)(ulRTPTS>>8); 
  741. *pc++ = (UINT8)(ulRTPTS);
  742.     }
  743.     return theErr;
  744. }
  745. HX_RESULT
  746. FixRTCPSR(IHXCommonClassFactory* pCCF, 
  747.   IHXBuffer* pOrigBuf, 
  748.   REF(IHXBuffer*) pNewBuf, 
  749.   UINT32 ulRTPTSOffset)
  750. {
  751.     BYTE* pcOrig = pOrigBuf->GetBuffer();
  752.     if (pOrigBuf->GetSize() < 20)
  753.     {
  754. return HXR_INVALID_PARAMETER;
  755.     } 
  756.     else
  757.     {
  758. // make sure it's SR
  759. if (RTCP_SR != *(pcOrig+1))
  760. {
  761.     return HXR_IGNORE;
  762. }
  763.     }
  764.     
  765.     HX_RESULT theErr = pCCF->CreateInstance(IID_IHXBuffer, (void**) &pNewBuf);
  766.     if (HXR_OK == theErr)
  767.     {
  768. theErr = pNewBuf->Set(pOrigBuf->GetBuffer(), pOrigBuf->GetSize());
  769.     }
  770.     if (HXR_OK == theErr)
  771.     {
  772. UINT32 ulRTPTS = 0;
  773. pcOrig += 16;     
  774.         ulRTPTS = GetDwordFromBufAndInc(pcOrig);
  775.         UINT32 lA = ulRTPTS;
  776. // update
  777. ulRTPTS += ulRTPTSOffset;
  778.  
  779. BYTE* pc = pNewBuf->GetBuffer();
  780. pc += 16;
  781. //RTP Timestamp
  782. *pc++ = (UINT8)(ulRTPTS>>24); 
  783. *pc++ = (UINT8)(ulRTPTS>>16); 
  784. *pc++ = (UINT8)(ulRTPTS>>8); 
  785. *pc++ = (UINT8)(ulRTPTS);
  786.     }
  787.     return theErr;    
  788. }
  789. void
  790. RTPBaseTransport::SyncTimestamp(IHXPacket* pPacket)
  791. {
  792.     IHXTimeStampSync* pTSSync = NULL;
  793.     if (FAILED(
  794. m_pResp->QueryInterface(IID_IHXTimeStampSync, (void**)&pTSSync)))
  795.     {
  796. // this shouldn't happen...
  797. HX_ASSERT(!"IHXTimeStampSync not implemented");
  798. return;
  799.     }
  800.     UINT32 ulInitialRefTime = 0;
  801.     UINT32 ulInitialThisTime = pPacket->GetTime();
  802.     if (pTSSync->NeedInitialTS(m_sessionID))
  803.     {
  804. pTSSync->SetInitialTS(m_sessionID, pPacket->GetTime());
  805. ulInitialRefTime = ulInitialThisTime;
  806.     }
  807.     else
  808.     {
  809. ulInitialRefTime = pTSSync->GetInitialTS(m_sessionID);
  810.     }
  811.     HX_RELEASE(pTSSync);
  812.     
  813.     RTSPStreamData* pStreamData = 
  814. m_pStreamHandler->getStreamData(pPacket->GetStreamNumber());
  815.     HX_ASSERT(pStreamData != NULL);
  816.     if (pStreamData)
  817.     {
  818. // calc the difference b/n reference stream
  819. if (ulInitialThisTime >= ulInitialRefTime)
  820. {
  821.     // we want RTP time
  822.     if (pStreamData->m_pTSConverter)
  823.     {
  824. m_lTimeOffsetRTP = 
  825.     pStreamData->m_pTSConverter->hxa2rtp(ulInitialThisTime - ulInitialRefTime);
  826.     }
  827.     else
  828.     {
  829. m_lTimeOffsetRTP = ulInitialThisTime - ulInitialRefTime;
  830.     }     
  831. }
  832. else
  833. {
  834.     // we want RTP time
  835.     if (pStreamData->m_pTSConverter)
  836.     {
  837. m_lTimeOffsetRTP = 
  838.     pStreamData->m_pTSConverter->hxa2rtp(ulInitialRefTime - ulInitialThisTime);
  839.     }
  840.     else
  841.     {
  842. m_lTimeOffsetRTP = ulInitialRefTime - ulInitialThisTime;
  843.     }     
  844.     
  845.     m_lTimeOffsetRTP *= -1;
  846. }
  847.     }
  848. }
  849. // The pPacketBuf is returned with an AddRef(), as it must.
  850. HX_RESULT
  851. RTPBaseTransport::makePacket(BasePacket* pBasePacket, 
  852.     REF(IHXBuffer*) pPacketBuf)
  853. {
  854.     if(!m_bIsSource)
  855.     {
  856. HX_ASSERT(!"Player shouldn't be making pkt");
  857. return HXR_UNEXPECTED;
  858.     }
  859.     IHXPacket* pPacket = pBasePacket->GetPacket();
  860.     if (!pPacket)
  861.     {
  862. return HXR_UNEXPECTED;
  863.     }
  864.     else if (pPacket->IsLost())
  865.     {
  866. pPacket->Release();
  867. return HXR_OK;
  868.     }
  869.  
  870.     IHXBuffer* pBuffer = pPacket->GetBuffer();
  871.     UINT32 bufLen = pBuffer->GetSize();
  872.     UINT16 streamNumber = pPacket->GetStreamNumber();
  873.     UINT16 ruleNumber = pPacket->GetASMRuleNumber();
  874.     UINT8  ruleFlags = pPacket->GetASMFlags();
  875.     // it better be the same
  876.     HX_ASSERT(m_streamNumber == streamNumber);
  877.     RTSPStreamData* pStreamData = 
  878. m_pStreamHandler->getStreamData(streamNumber);
  879.     //XXXBAB
  880.     if (!pStreamData->m_packetSent)
  881.     {
  882. pStreamData->m_packetSent = TRUE;
  883.     }
  884.     
  885.     pStreamData->m_seqNo = pBasePacket->m_uSequenceNumber;
  886.     /*
  887.      * Make RTP Packet
  888.      */
  889.     RTPPacket pkt;
  890.     HX_RESULT hresult = HXR_OK;
  891.     BOOL bCompressed = FALSE; //XXXBAB don't compress anything yet...
  892.     UINT32 packetLen = 0;
  893.     pkt.version_flag = 2;
  894.     pkt.padding_flag = 0;
  895.     pkt.csrc_len = 0;
  896.     /*
  897.      * Basics
  898.      */
  899.     pkt.seq_no = pStreamData->m_seqNo;
  900.     pkt.data.data = (INT8*)pBuffer->GetBuffer();
  901.     pkt.data.len = HX_SAFEINT(pBuffer->GetSize());
  902.     pkt.ssrc = m_pReportHandler->GetSSRC();
  903.     pkt.extension_flag = 0;
  904.     pkt.payload = m_rtpPayloadType;
  905.     /*
  906.      * IHXRTPPacket support
  907.      */
  908.     if (pStreamData->m_bFirstPacket)
  909.     {
  910. // figure out pkt type
  911. IHXRTPPacket* pRTPPacket = NULL;
  912. pStreamData->m_bUsesRTPPackets = (pPacket->QueryInterface(
  913.     IID_IHXRTPPacket, 
  914.     (void**) &pRTPPacket)
  915.   == HXR_OK);
  916. if (pStreamData->m_bUsesRTPPackets)
  917. {
  918.     HX_ASSERT(pRTPPacket == pPacket);
  919.     if (pRTPPacket != pPacket)
  920.     {
  921. return HXR_INVALID_PARAMETER;
  922.     }
  923. }
  924. HX_RELEASE(pRTPPacket);
  925. // figure out marker bit handling routine
  926. if (NULL == m_pMBitHandler)
  927. {
  928.     IHXRTPPacketInfo* pRTPPacketInfo = NULL;
  929.     if (pPacket->QueryInterface(IID_IHXRTPPacketInfo, (void**) &pRTPPacketInfo) == HXR_OK)
  930.     {
  931.      m_pMBitHandler = &RTPBaseTransport::MBitRTPPktInfo;
  932.      pRTPPacketInfo->Release();
  933.     }
  934.     else
  935.     {
  936.      m_pMBitHandler = &RTPBaseTransport::MBitASMRuleNo;
  937.     }
  938.      }
  939.     }
  940.     /* 
  941.      * Marker Bit
  942.      */
  943.     (this->*m_pMBitHandler)(pkt.marker_flag, pPacket, ruleNumber);
  944.     if (m_bRTPTimeSet)
  945.     {
  946. SyncTimestamp(pPacket);
  947.     }     
  948.     /*
  949.      * Timestamp
  950.      */
  951.     if (pStreamData->m_bUsesRTPPackets)
  952.     {
  953. pkt.timestamp = ((IHXRTPPacket*) pPacket)->GetRTPTime();
  954.     }
  955.     else if (pStreamData->m_pTSConverter)
  956.     {
  957. pkt.timestamp = 
  958.     pStreamData->m_pTSConverter->hxa2rtp(pPacket->GetTime());
  959.     }
  960.     else
  961.     {
  962. pkt.timestamp = pPacket->GetTime();
  963.     }
  964.     /*
  965.      * Extension and asm rule
  966.      */
  967.     if (RTP_OP_ASMRULES == m_ulExtensionSupport)
  968.     {
  969. // this is the only one right now.
  970. pkt.extension_flag = 1;
  971. pkt.op_code = RTP_OP_ASMRULES;
  972. pkt.op_code_data_length = 1;
  973. pkt.asm_flags = ruleFlags;
  974. pkt.asm_rule = ruleNumber;
  975.     }
  976.     else
  977.     {
  978. pkt.extension_flag = 0;
  979.     }
  980.     if (pStreamData->m_bFirstPacket)
  981.     {
  982. m_pRTCPTran->startScheduler();
  983. m_pRTCPTran->m_bSendBye = TRUE;
  984. pStreamData->m_bFirstPacket = FALSE;
  985. // init report handler with starting NTP time and
  986. // 0 RTP time as the reference point.
  987. m_pReportHandler->Init(*m_pFirstPlayTime, 
  988.        0, 
  989.        pStreamData->m_pTSConverter);
  990. // at this point, it should have the same stream number
  991. HX_ASSERT(m_streamNumber == m_pRTCPTran->m_streamNumber);
  992. HX_ASSERT(m_bRTPTimeSet);
  993.     }
  994.     // externally, we need to offset the timestamp...
  995.     // 
  996.     // XXXGo 
  997.     // In RTSP PLAY Response msg, there is a RTP-Info header in which there 
  998.     // is a rtp timestap that corresponds to NTP time spesified in PLAY Request.  
  999.     // Since PLAY Response goes out before we ever receive the first pkt, it 
  1000.     // always returns RTP time equivalent of NTP time in a Range header as a timestamp. 
  1001.     // So, we need to offset the timestamp here.  
  1002.     // In future, we might want to change the calling sequence so we don't have to do this...    
  1003.     if (m_bRTPTimeSet)
  1004.     {
  1005.         INT64 nNewRTPOffset = 0;
  1006.         UINT32 ulRawRTPTime = 0;
  1007.         HXTimeval hxNow = m_pScheduler->GetCurrentSchedulerTime();
  1008.         Timeval tvNow;
  1009. NTPTime ntpNow;
  1010. // Convert scheduler time to something we can use.
  1011.         tvNow.tv_sec = hxNow.tv_sec;
  1012.         tvNow.tv_usec = hxNow.tv_usec;
  1013.         ntpNow = NTPTime(tvNow);
  1014.         if (pStreamData->m_pTSConverter)
  1015.         {
  1016.             ulRawRTPTime = pStreamData->m_pTSConverter->hxa2rtp((UINT32)(ntpNow - m_pReportHandler->GetNTPBase()));
  1017.         }
  1018.         else
  1019.         {
  1020.             ulRawRTPTime = (UINT32)(ntpNow - m_pReportHandler->GetNTPBase());
  1021.         }
  1022. nNewRTPOffset = CAST_TO_INT64 pkt.timestamp - CAST_TO_INT64 ulRawRTPTime;
  1023.         m_pReportHandler->SetRTPBase(nNewRTPOffset);
  1024. // if this is true, there was a Range header in a PLAY request
  1025. m_bRTPTimeSet = FALSE;
  1026. if (m_bIsLive)
  1027. {
  1028.     m_ulBaseTS = pkt.timestamp - m_lTimeOffsetRTP;
  1029. }
  1030.     }
  1031.     if (m_bIsLive)
  1032.     {
  1033.      pkt.timestamp -= m_ulBaseTS;
  1034.     }
  1035.     pStreamData->m_lastTimestamp = pkt.timestamp;
  1036.     /*
  1037.      * Create enough space to account for the op code and
  1038.      * op code data if the extension bit is set
  1039.      */
  1040.     packetLen = pkt.static_size() + pBuffer->GetSize() + 
  1041. (pkt.extension_flag 
  1042. ? sizeof(UINT16) + (pkt.op_code_data_length * sizeof(UINT32))
  1043. : 0);
  1044.     IHXBuffer* pPacketOut = NULL;
  1045.     m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
  1046.                                           (void**)&pPacketOut);
  1047.     if(pPacketOut)
  1048.     {
  1049.         pPacketOut->SetSize(packetLen);
  1050.         pkt.pack(pPacketOut->GetBuffer(), packetLen);
  1051.         pPacketOut->SetSize(packetLen);  //update with actual packed length
  1052. #ifdef DEBUG
  1053.         if (m_drop_packets && ++m_packets_since_last_drop % 10 == 0)
  1054.         {
  1055.     goto RTPsendContinue;
  1056.         }
  1057. #endif /* DEBUG */
  1058.         updateQoSInfo(bufLen);
  1059.         // out params...
  1060.         pPacketBuf = pPacketOut;
  1061.         /* update */
  1062.         m_pReportHandler->OnRTPSend(pkt.seq_no, 1, pBasePacket->GetSize(), pkt.timestamp);    
  1063.     }
  1064.     else
  1065.     {
  1066.         hresult = HXR_OUTOFMEMORY;
  1067.     }
  1068. #ifdef DEBUG
  1069. RTPsendContinue:
  1070. #endif    
  1071.     pBuffer->Release();
  1072.     pPacket->Release();
  1073.     return hresult;
  1074. }
  1075. HX_RESULT
  1076. RTPBaseTransport::handlePacket(IHXBuffer* pBuffer)
  1077. {
  1078.     if (!m_ulPacketsSent && m_bEmulatePVSession)
  1079.     {
  1080.         /* XXXMC 
  1081.          * Special-case handling for PV clients
  1082.          */
  1083.         UINT8* pUDPPktPayload = pBuffer->GetBuffer();
  1084.         UINT8 ucRTPVersion  = (*pUDPPktPayload & 0xc0)>>6;
  1085.         if(ucRTPVersion != 2)
  1086.         {
  1087.             DPRINTF(D_INFO, ("RTP: PV CLIENT PKT RECVDn"));
  1088.             this->sendPVHandshakeResponse(pUDPPktPayload);
  1089.             return HXR_OK;
  1090.         }
  1091.     }
  1092.     return _handlePacket(pBuffer, TRUE);
  1093. }
  1094. HX_RESULT
  1095. RTPBaseTransport::_handlePacket(IHXBuffer* pBuffer, BOOL bIsRealTime)
  1096. {
  1097.     RTPPacket pkt;
  1098.     UINT32 timeStampHX = 0;
  1099.     UINT32 timeStampRTP = 0;
  1100.     HX_RESULT hresult = HXR_OK;
  1101.     BOOL bHasASMRules = FALSE;
  1102.     if (m_bIsSource)
  1103.     {
  1104. return HXR_OK;
  1105.     }
  1106.     if(pkt.unpack(pBuffer->GetBuffer(), pBuffer->GetSize()) == 0)
  1107.     {
  1108. return HXR_UNEXPECTED;
  1109.     }
  1110.     
  1111.     if(pkt.version_flag != 2)
  1112.     {
  1113. return HXR_INVALID_VERSION;
  1114.     }
  1115.     // ignore the packets not matching the payload type
  1116.     if (pkt.payload != m_rtpPayloadType)
  1117.     {
  1118.         return HXR_OK;
  1119.     }
  1120.     // stick with the 1st ssrc with the same payload type
  1121.     if (!m_bSSRCDetermined)
  1122.     {
  1123.         m_bSSRCDetermined = TRUE;
  1124.         m_ulSSRCDetermined = pkt.ssrc;
  1125.         m_pRTCPTran->setSSRC(m_ulSSRCDetermined);
  1126.     }
  1127.     // ignore the packets with different ssrc but with the same payload time
  1128.     else if (m_ulSSRCDetermined != pkt.ssrc)
  1129.     {
  1130.         return HXR_OK;
  1131.     }
  1132.     RTSPStreamData* pStreamData = m_pStreamHandler->getStreamData(m_streamNumber);
  1133.     HX_ASSERT(pStreamData != NULL);
  1134.     // If this function is called in Real-Time, handle RTCP response as needed
  1135.     if (bIsRealTime)
  1136.     {
  1137. HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
  1138. ULONG32 ulPktRcvTime = rmatv.tv_sec*1000 + rmatv.tv_usec/1000;
  1139. // Convert reception time to the packet time stamp units
  1140. if (m_pRTCPTran->GetTSConverter())
  1141. {
  1142.     ulPktRcvTime = m_pRTCPTran->GetTSConverter()->hxa2rtp(ulPktRcvTime);
  1143. }
  1144. // Gather data for RTCP RR
  1145. if (pStreamData->m_bFirstPacket)
  1146. {
  1147.     if (!m_pRTCPTran->isShedulerStarted())
  1148.     {
  1149. m_pRTCPTran->startScheduler();
  1150.     }
  1151. }
  1152. /* update */
  1153. m_pReportHandler->OnRTPReceive(pkt.ssrc, 
  1154.        pkt.seq_no,
  1155.        pkt.timestamp, 
  1156.        ulPktRcvTime);
  1157. /* send RR if necessary */
  1158. if (m_pRTCPTran->m_bSendReport && m_pRTCPTran->m_bSendRTCP)
  1159. {
  1160.     m_pRTCPTran->sendReceiverReport();
  1161.     m_pRTCPTran->m_bSendReport = FALSE;
  1162.     m_pRTCPTran->scheduleNextReport();
  1163. }
  1164.     }
  1165.     // If we are waiting for the start info, we cannot place the
  1166.     // packets into the transport buffer yet since we need the
  1167.     // start info to proper scale and offset the packet time
  1168.     // stamps
  1169.     if (m_bWaitForStartInfo)
  1170.     {
  1171. if (m_StartInfoWaitQueue.GetCount() == 0)
  1172. {
  1173.     // First packet received
  1174.     m_ulStartInfoWaitStartTime = HX_GET_TICKCOUNT();
  1175.     m_uFirstSeqNum = pkt.seq_no;
  1176.     m_ulFirstRTPTS = pkt.timestamp;
  1177.     // For Live stream, postpone identification of first packet until we get
  1178.     // a contiguous sequence (some servers have discontinuity on start 
  1179.     // of live streams)
  1180.     if (!m_bIsLive)
  1181.     {
  1182. m_bFirstSet = TRUE;
  1183.     }
  1184. }
  1185. else
  1186. {
  1187.     LONG32 lSeqNumDelta = ((LONG32) (((UINT16) pkt.seq_no) - m_uFirstSeqNum));
  1188.     // First SeqNum and First TS need not belong to the same packet
  1189.     // We are really looking for the lowest seq. num and lowest time
  1190.     // stamp so that we do not throw away any packets and so that the
  1191.     // time is not wrapped before 0
  1192.     if (lSeqNumDelta < 0)
  1193.     {
  1194. m_uFirstSeqNum = pkt.seq_no;
  1195.     }
  1196.     else if (!m_bFirstSet)
  1197.     {
  1198. // If we have not encountered continuty yet, look for it
  1199. if (lSeqNumDelta > MAX_NUM_PACKETS_GAPPED_FOR_LIVE_START)
  1200. {
  1201.     resetStartInfoWaitQueue();
  1202.     m_uFirstSeqNum = pkt.seq_no;
  1203.     m_ulFirstRTPTS = pkt.timestamp;
  1204. }
  1205. else
  1206. {
  1207.     // Continuity found - we have the start
  1208.     m_bFirstSet = TRUE;
  1209. }
  1210.     }
  1211.     if (((LONG32) (m_ulFirstRTPTS - pkt.timestamp)) > 0)
  1212.     {
  1213. m_ulFirstRTPTS = pkt.timestamp;
  1214.     }
  1215. }
  1216. pBuffer->AddRef();
  1217. m_StartInfoWaitQueue.AddTail(pBuffer);
  1218. /* If start Info has been at least partially set or the wait has been
  1219.    aborted for some reason (usually when we know it will not be set 
  1220.    through out-of band methods <-> RTP Info did not contain start Info
  1221.    we need) or we time-out, stop waiting and hand off acumulated 
  1222.            packets to the transport buffer.
  1223.    Also if starting seq. number is not explicitly communicated,
  1224.    scan through few starting packets until we have a good starting 
  1225.    sequence number (contiguous) since some servers send lossy streams 
  1226.    in the beginning. */
  1227.   if (m_bSeqNoSet || 
  1228.     ((m_bRTPTimeSet || m_bAbortWaitForStartInfo) && 
  1229.      ((!m_bIsLive) || (m_StartInfoWaitQueue.GetCount() >= MIN_NUM_PACKETS_SCANNED_FOR_LIVE_START))) ||
  1230.       ((HX_GET_TICKCOUNT() - m_ulStartInfoWaitStartTime) > 
  1231.        MAX_STARTINFO_WAIT_TIME))
  1232. {
  1233.     IHXBuffer* pStoredBuffer;
  1234.     m_bWaitForStartInfo = FALSE;
  1235.     m_bAbortWaitForStartInfo = FALSE;
  1236.     m_bFirstSet = TRUE;
  1237.     while (!m_StartInfoWaitQueue.IsEmpty())
  1238.     {
  1239. pStoredBuffer = (IHXBuffer*) m_StartInfoWaitQueue.RemoveHead();
  1240. if (pStoredBuffer)
  1241. {
  1242.     _handlePacket(pStoredBuffer, FALSE);
  1243.     pStoredBuffer->Release();
  1244. }
  1245.     }
  1246. }
  1247. return HXR_OK;
  1248.     }
  1249.     /*
  1250.      * Extension and asm rule
  1251.      */
  1252.     if (pkt.extension_flag == 1)
  1253.     {
  1254. HX_ASSERT(RTP_OP_PACKETFLAGS != pkt.op_code);
  1255. if (RTP_OP_ASMRULES == pkt.op_code)
  1256. {
  1257.     bHasASMRules = TRUE;
  1258. }
  1259.     }
  1260.     /*
  1261.      * RTP-Info:  if either one of them were not in RTP-Info, we need to set 
  1262.      * it right here.
  1263.      */
  1264.     if (!m_bSeqNoSet)
  1265.     {
  1266. if (!m_bFirstSet)
  1267. {
  1268.     m_uFirstSeqNum = pkt.seq_no;
  1269. }
  1270. #ifdef RTP_MESSAGE_DEBUG
  1271. messageFormatDebugFileOut("INIT: StartSeqNum not in RTP-Info");
  1272. #endif // RTP_MESSAGE_DEBUG
  1273. setFirstSeqNum(m_streamNumber, m_uFirstSeqNum);
  1274.     }     
  1275.     if (!m_bRTPTimeSet)
  1276.     {
  1277. if (!m_bFirstSet)
  1278. {
  1279.     m_ulFirstRTPTS = pkt.timestamp;
  1280. }
  1281. #ifdef RTP_MESSAGE_DEBUG
  1282. messageFormatDebugFileOut("INIT: RTPOffset not in RTP-Info");
  1283. #endif // RTP_MESSAGE_DEBUG
  1284. setFirstTimeStamp(m_streamNumber, m_ulFirstRTPTS);
  1285. m_bWeakStartSync = TRUE;
  1286.     }
  1287.     
  1288.     /*
  1289.      * TimeStamp
  1290.      */    
  1291.     // for RealMedia in scalable multicast, we don't want to adjust
  1292.     // the timestamp since the packets' time is in ms already and 
  1293.     // A/V is always in sync
  1294.     if (m_bSkipTimeAdjustment)
  1295.     {
  1296.         timeStampRTP = timeStampHX = pkt.timestamp;
  1297.     }
  1298.     else if (m_bLastTSSet && (m_ulLastRawRTPTS == (ULONG32)pkt.timestamp))
  1299.     {
  1300. // We want to preserve same time stamped packet sequences
  1301. // since some payloads may depend on it for proper coded frame
  1302. // assembly
  1303. timeStampRTP = m_ulLastRTPTS;
  1304. timeStampHX = m_ulLastHXTS;
  1305.     }
  1306.     else
  1307.     {
  1308. if (pStreamData->m_pTSConverter)
  1309. {
  1310.     timeStampHX = pStreamData->m_pTSConverter->rtp2hxa(pkt.timestamp);
  1311. }
  1312. else
  1313. {
  1314.     timeStampHX = pkt.timestamp;
  1315. }
  1316. timeStampHX += (m_lSyncOffsetHX + 
  1317.  m_lOffsetToMasterHX - 
  1318.  m_lTimeOffsetHX);  
  1319. timeStampRTP = (pkt.timestamp +
  1320. m_lSyncOffsetRTP +
  1321. m_lOffsetToMasterRTP - 
  1322. m_lTimeOffsetRTP);
  1323. m_ulLastHXTS = timeStampHX;
  1324. m_ulLastRTPTS = timeStampRTP;
  1325. m_ulLastRawRTPTS = pkt.timestamp;
  1326. m_bLastTSSet = TRUE;
  1327.     }
  1328. #ifdef RTP_MESSAGE_DEBUG
  1329.     if (m_bMessageDebug)
  1330.     {
  1331. messageFormatDebugFileOut("PKT: (Seq=%6u,RTPTime=%10u) -> (HXTimeval=%10u,RTPTimeval=%10u)",
  1332.   ((UINT16) pkt.seq_no), pkt.timestamp,
  1333.   timeStampHX, timeStampRTP);   
  1334.     }
  1335. #endif // RTP_MESSAGE_DEBUG
  1336.     
  1337.     pStreamData->m_bFirstPacket = FALSE;
  1338.     
  1339.     CHXPacket* pPacket = new CHXRTPPacket;
  1340.     if(pPacket)
  1341.     {
  1342.         pPacket->AddRef();
  1343.     }
  1344.     else
  1345.     {
  1346.         hresult = HXR_OUTOFMEMORY;
  1347.     }
  1348.     UINT32 dataOffset=
  1349.         (UINT32)((PTR_INT)pkt.data.data - (PTR_INT)pBuffer->GetBuffer());
  1350.     IHXBuffer* pPktBuffer = 
  1351.         new CHXStaticBuffer(pBuffer, dataOffset, pkt.data.len);
  1352.     if(pPktBuffer)
  1353.     {
  1354.         pPktBuffer->AddRef();
  1355.     }
  1356.     else
  1357.     {
  1358.         hresult = HXR_OUTOFMEMORY;
  1359.     }
  1360.     if( hresult == HXR_OUTOFMEMORY )
  1361.     {
  1362.         HX_RELEASE(pPacket);
  1363.         return hresult;
  1364.     } 
  1365.     
  1366.     if (bHasASMRules)
  1367.     {
  1368. pPacket->SetRTP(pPktBuffer, timeStampHX, timeStampRTP, m_streamNumber,
  1369. (UINT8) pkt.asm_flags, pkt.asm_rule);
  1370.     }
  1371.     else if(pkt.marker_flag == 1 && m_bHasMarkerRule)
  1372.     {
  1373. pPacket->SetRTP(pPktBuffer, timeStampHX, timeStampRTP, m_streamNumber,
  1374. HX_ASM_SWITCH_ON | HX_ASM_SWITCH_OFF, m_markerRuleNumber);
  1375.     }
  1376.     else
  1377.     {
  1378. pPacket->SetRTP(pPktBuffer, timeStampHX, timeStampRTP, m_streamNumber,
  1379.     HX_ASM_SWITCH_ON | HX_ASM_SWITCH_OFF, pkt.marker_flag ? 1 : 0);
  1380.     }
  1381.     
  1382.     if (m_bIsSource)
  1383.     {
  1384. hresult = m_pResp->PacketReady(HXR_OK, 
  1385.        m_sessionID, 
  1386.        pPacket);
  1387.     }
  1388.     else
  1389.     {
  1390. hresult = storePacket(pPacket,
  1391.                       m_streamNumber,
  1392.                       pkt.seq_no,
  1393.                       0,
  1394.                       0);
  1395.     }
  1396.     pPktBuffer->Release();
  1397.     pPacket->Release();
  1398.     return hresult;
  1399. }
  1400. HX_RESULT 
  1401. RTPBaseTransport::handleRTCPSync(NTPTime ntpTime, ULONG32 ulRTPTime)
  1402. {
  1403.     HX_RESULT retVal = HXR_IGNORE;
  1404.     // We use RTCP synchronization on live streams only.
  1405.     // Static streams have no reason not to be synchronzied in RTP time.
  1406.     // Making use of RTCP for static streams may result in unwanted sync.
  1407.     // noise/error for servers who do not generate proper RTCP ntp-rtp
  1408.     // mapping.  RealServers prior to RealServer9 had error in RTCP reported
  1409.     // ntp-rtp mapping (max. error 1s, avg 500ms).
  1410.     if ((m_bIsLive || m_bWeakStartSync) && !m_bSkipTimeAdjustment)
  1411.     {
  1412. ULONG32 ulNtpHX = ntpTime.toMSec();
  1413. RTSPStreamData* pStreamData = 
  1414.     m_pStreamHandler->getStreamData(m_streamNumber);
  1415. #ifdef RTP_MESSAGE_DEBUG
  1416. messageFormatDebugFileOut("RTCP-SYNC: Received NTPTime=%u RTPTime=%u", 
  1417.   ulNtpHX, ulRTPTime);
  1418. #endif // RTP_MESSAGE_DEBUG
  1419. // We ignore the RTCP sync until we can compute npt (m_bRTPTimeSet) or
  1420. // if the RTCP packet contains no synchronization information 
  1421. // (ulNtpHX == 0)
  1422. if (pStreamData && (ulNtpHX != 0) && m_bRTPTimeSet)
  1423. {
  1424.     // Npt time can be computed (ulHXTime)
  1425.     ULONG32 ulHXTime = pStreamData->m_pTSConverter->rtp2hxa(ulRTPTime);
  1426.     
  1427.     retVal = HXR_OK;
  1428.     
  1429.     if ((!m_pSyncServer) && m_pResp)
  1430.     {
  1431. m_pResp->QueryInterface(IID_IHXTransportSyncServer, 
  1432. (void**) &m_pSyncServer);
  1433.     }
  1434.     
  1435.     if (m_bNTPtoHXOffsetSet)
  1436.     {
  1437. // We can sync - NTP to NPT offset is known
  1438. ULONG32 ulExpectedHXTime = ulNtpHX + m_lNTPtoHXOffset;
  1439. LONG32 lSyncOffsetHX = ulExpectedHXTime - ulHXTime;
  1440. LONG32 lSyncOffsetChange = lSyncOffsetHX - m_lSyncOffsetHX;
  1441. if ((lSyncOffsetChange > ACCEPTABLE_SYNC_NOISE) ||
  1442.     (lSyncOffsetChange < (-ACCEPTABLE_SYNC_NOISE)))
  1443. {
  1444.     if (m_bIsSyncMaster && m_pSyncServer)
  1445.     {
  1446. #ifdef RTP_MESSAGE_DEBUG
  1447. messageFormatDebugFileOut("RTCP-SYNC: Distribute Master Sync NPTTime=%u SyncOffset=%d", 
  1448.           ulHXTime, -lSyncOffsetHX);
  1449. #endif // RTP_MESSAGE_DEBUG
  1450. m_pSyncServer->DistributeSync(ulHXTime, -lSyncOffsetHX);
  1451.     }
  1452.     else
  1453.     {
  1454. m_lSyncOffsetHX = lSyncOffsetHX;
  1455. if (lSyncOffsetHX >= 0)
  1456. {
  1457.     m_lSyncOffsetRTP = (LONG32) 
  1458. (pStreamData->m_pTSConverter->hxa2rtp_raw((ULONG32) lSyncOffsetHX));
  1459. }
  1460. else
  1461. {
  1462.     m_lSyncOffsetRTP = (LONG32) 
  1463. (-pStreamData->m_pTSConverter->hxa2rtp_raw((ULONG32) (-lSyncOffsetHX)));
  1464. }
  1465. #ifdef RTP_MESSAGE_DEBUG
  1466. messageFormatDebugFileOut("RTCP-SYNC: Self-Sync SyncOffset=%d SyncOffsetRTP=%d", 
  1467.           m_lSyncOffsetHX, m_lSyncOffsetRTP);
  1468. #endif // RTP_MESSAGE_DEBUG
  1469.     }
  1470. }
  1471.     }
  1472.     else
  1473.     {
  1474. // This the first RTCP sync accross all streams, anchor sync
  1475. if (m_pSyncServer)
  1476. {
  1477. #ifdef RTP_MESSAGE_DEBUG
  1478.     messageFormatDebugFileOut("RTCP-SYNC: Distribute NTP-NPT Mapping NTPTime=%u NPTTime=%u", 
  1479.       ulNtpHX, ulHXTime);
  1480. #endif // RTP_MESSAGE_DEBUG
  1481.     m_pSyncServer->DistributeSyncAnchor(ulHXTime, ulNtpHX);
  1482. }
  1483.     }
  1484. }
  1485.     }
  1486.     return retVal;
  1487. }
  1488. HX_RESULT
  1489. RTPBaseTransport::anchorSync(ULONG32 ulHXTime, ULONG32 ulNTPTime)
  1490. {
  1491.     HX_RESULT retVal = HXR_OK;
  1492.     m_lNTPtoHXOffset = ulHXTime - ulNTPTime;
  1493.     m_bNTPtoHXOffsetSet = TRUE;
  1494. #ifdef RTP_MESSAGE_DEBUG
  1495.     messageFormatDebugFileOut("RTCP-SYNC: Received NTP-NPT Mapping NTPTime=%u NPTTime=%u NTPtoNPTOffset=%d", 
  1496.       ulNTPTime, ulHXTime, m_lNTPtoHXOffset);
  1497. #endif // RTP_MESSAGE_DEBUG
  1498.     return retVal;
  1499. }
  1500. HX_RESULT 
  1501. RTPBaseTransport::handleMasterSync(ULONG32 ulHXTime, LONG32 lHXOffsetToMaster)
  1502. {
  1503.     HX_RESULT retVal = HXR_IGNORE;
  1504.     RTSPStreamData* pStreamData = 
  1505.     m_pStreamHandler->getStreamData(m_streamNumber);
  1506.     if (pStreamData && (!m_bIsSyncMaster))
  1507.     {
  1508. retVal = HXR_OK;
  1509. m_lOffsetToMasterHX = lHXOffsetToMaster;
  1510. if (lHXOffsetToMaster >= 0)
  1511. {
  1512.     m_lOffsetToMasterRTP = (LONG32) 
  1513. (pStreamData->m_pTSConverter->hxa2rtp_raw((ULONG32) lHXOffsetToMaster));
  1514. }
  1515. else
  1516. {
  1517.     m_lOffsetToMasterRTP = (LONG32) 
  1518. (-pStreamData->m_pTSConverter->hxa2rtp_raw((ULONG32) (-lHXOffsetToMaster)));
  1519. }
  1520. #ifdef RTP_MESSAGE_DEBUG
  1521. messageFormatDebugFileOut("RTCP-SYNC: Master-Sync NPTTime=%u MasterSyncOffset=%d MasterSyncOffsetRTP=%d", 
  1522.   ulHXTime, m_lOffsetToMasterHX, m_lOffsetToMasterRTP);
  1523. #endif // RTP_MESSAGE_DEBUG
  1524.     }
  1525.     return retVal;
  1526. }
  1527. void
  1528. RTPBaseTransport::resetStartInfoWaitQueue(void)
  1529. {
  1530.     IHXBuffer* pStoredBuffer;
  1531.     while (!m_StartInfoWaitQueue.IsEmpty())
  1532.     {
  1533. pStoredBuffer = (IHXBuffer*) m_StartInfoWaitQueue.RemoveHead();
  1534. HX_RELEASE(pStoredBuffer);
  1535.     }
  1536. }
  1537. HX_RESULT
  1538. RTPBaseTransport::streamDone(UINT16 streamNumber)
  1539. {
  1540.     HX_ASSERT(m_streamNumber == streamNumber);
  1541.     HX_ASSERT(m_streamNumber == m_pRTCPTran->m_streamNumber);
  1542.     HX_RESULT hresult = HXR_OK;
  1543.     HX_ASSERT(m_pRTCPTran);
  1544.     if (!m_bActive)
  1545.     {
  1546. // this stream is not active, don't do anything.
  1547.     }
  1548.     else if (m_bIsSource)
  1549.     {
  1550. hresult= m_pRTCPTran->streamDone(streamNumber);
  1551.     }
  1552.     else
  1553.     {
  1554.      // send BYE pkt
  1555.      m_pRTCPTran->streamDone(streamNumber);
  1556. hresult = m_pResp->OnStreamDone(HXR_OK, streamNumber);
  1557.     }
  1558.     return hresult;
  1559. }
  1560. STDMETHODIMP
  1561. RTPBaseTransport::InitBw(IHXBandwidthManagerInput* pBwMgr)
  1562. {
  1563.     HX_RELEASE(m_pBwMgrInput);
  1564.     m_pBwMgrInput = pBwMgr;
  1565.     pBwMgr->AddRef();
  1566.     return HXR_OK;
  1567. }
  1568. STDMETHODIMP
  1569. RTPBaseTransport::SetTransmitRate(UINT32 ulBitRate)
  1570. {
  1571.     return HXR_OK;
  1572. }
  1573. /*
  1574.  * XXXMC
  1575.  * Special-case handling for PV clients
  1576.  */
  1577. void
  1578. RTPBaseTransport::setPVEmulationMode(BOOL bPVSessionFlag)
  1579. {
  1580.     m_bEmulatePVSession = bPVSessionFlag;
  1581. }
  1582. void
  1583. RTPBaseTransport::setRTCPTransport(RTCPBaseTransport* pRTCPTran)
  1584. {
  1585.     HX_ASSERT(pRTCPTran);
  1586.     HX_ASSERT(!m_pRTCPTran);
  1587.     m_pRTCPTran = pRTCPTran;
  1588.     m_pRTCPTran->AddRef();
  1589.     // pointing to the same instatnce
  1590.     HX_ASSERT(m_pReportHandler);
  1591.     m_pRTCPTran->m_pReportHandler = m_pReportHandler;
  1592. }
  1593. void 
  1594. RTPBaseTransport::MBitRTPPktInfo(REF(UINT8)bMBit, IHXPacket* pPkt, UINT16 unRuleNo)
  1595. {
  1596.     BOOL b = FALSE;
  1597.     IHXRTPPacketInfo* pRTPPacketInfo = NULL;
  1598.     if (pPkt->QueryInterface(IID_IHXRTPPacketInfo, (void**) &pRTPPacketInfo) == HXR_OK)
  1599.     {
  1600. if (pRTPPacketInfo->GetMarkerBit(b) == HXR_OK && b)
  1601. {
  1602.     bMBit = TRUE;
  1603. }
  1604. else
  1605. {
  1606.     bMBit = FALSE;
  1607. }
  1608. pRTPPacketInfo->Release();
  1609.     }
  1610.     else
  1611.     {
  1612. bMBit = FALSE;
  1613.     }
  1614. }
  1615. void 
  1616. RTPBaseTransport::MBitASMRuleNo(REF(UINT8)bMBit, IHXPacket* pPkt, UINT16 unRuleNo)
  1617. {
  1618.     bMBit = m_bHasMarkerRule && ((unRuleNo & 0x1) == m_markerRuleNumber);
  1619. }
  1620. #ifdef RTP_MESSAGE_DEBUG
  1621. void
  1622. RTPBaseTransport::messageFormatDebugFileOut(const char* fmt, ...)
  1623. {
  1624.     if(m_bMessageDebug)
  1625.     {
  1626. va_list args;
  1627. char buf[4096]; /* Flawfinder: ignore */
  1628. SafeSprintf(buf, 4096, "%s.%d", (const char*) m_messageDebugFileName, 
  1629.       m_streamNumber);
  1630. va_start(args, fmt);
  1631. FILE* fp = fopen(buf, "a");
  1632. if (fp)
  1633. {
  1634.     vsprintf(buf, fmt, args);
  1635.     fprintf(fp, "%sn", buf);
  1636.     fclose(fp);
  1637. }
  1638. va_end(args);
  1639.     }
  1640. }
  1641. #endif // RTP_MESSAGE_DEBUG
  1642. /*
  1643.  *   RTP UDP
  1644.  */
  1645. RTPUDPTransport::RTPUDPTransport(BOOL bIsSource)
  1646.     : RTPBaseTransport(bIsSource)
  1647.     , m_pUDPSocket(NULL)
  1648.     , m_foreignAddr(0)
  1649.     , m_foreignPort(0)
  1650.     , m_keepAliveSeq((UINT16)(random32(0) & 0xffff))
  1651.     , m_ulCurrentMulticastAddress(0)
  1652.     , m_ulCurrentMulticastPort(0)
  1653.     , m_pMCastUDPSocket(NULL)
  1654. {
  1655. }
  1656. RTPUDPTransport::~RTPUDPTransport()
  1657. {
  1658.     Done();
  1659. }
  1660. RTSPTransportTypeEnum
  1661. RTPUDPTransport::tag()
  1662. {
  1663.     return RTSP_TR_RTP_UDP;
  1664. }
  1665. void
  1666. RTPUDPTransport::Done()
  1667. {
  1668.     m_keepAlive.reset();
  1669.     if (m_pMCastUDPSocket)
  1670.     {
  1671.         m_pMCastUDPSocket->LeaveMulticastGroup(m_ulCurrentMulticastAddress, HXR_INADDR_ANY);
  1672.     }
  1673.     HX_RELEASE(m_pMCastUDPSocket);
  1674.     HX_RELEASE(m_pUDPSocket);
  1675.     RTPBaseTransport::Done();
  1676. }
  1677. HX_RESULT
  1678. RTPUDPTransport::init(IUnknown* pContext,
  1679.        IHXUDPSocket* pSocket,
  1680.        IHXRTSPTransportResponse* pResp)
  1681. {
  1682.     m_pResp = pResp;
  1683.     m_pResp->AddRef();
  1684.     
  1685.     m_pUDPSocket = pSocket;
  1686.     m_pUDPSocket->AddRef();
  1687.     /* Set DiffServ Code Point */
  1688.     IHXSetSocketOption* pOpt = NULL;
  1689.     if (SUCCEEDED(m_pUDPSocket->QueryInterface(IID_IHXSetSocketOption, (void**)&pOpt)))
  1690.     {
  1691. IHXQoSDiffServConfigurator* pCfg = NULL;
  1692. if (SUCCEEDED(pContext->QueryInterface(IID_IHXQoSDiffServConfigurator, (void**)&pCfg)))
  1693. {
  1694.     pCfg->ConfigureSocket(pOpt, HX_QOS_DIFFSERV_CLASS_MEDIA);
  1695.     pCfg->Release();
  1696.     pCfg = NULL;
  1697. }
  1698. pOpt->Release();
  1699. pOpt = NULL;
  1700.     }
  1701.     HX_RESULT hresult = Init(pContext);
  1702.     if(HXR_OK != hresult)
  1703.     {
  1704. return hresult;
  1705.     }
  1706. #ifdef DEBUG
  1707.     if (debug_func_level() & DF_DROP_PACKETS)
  1708.     {
  1709. m_drop_packets = TRUE;
  1710.     }
  1711. #endif /* DEBUG */
  1712.     RTPBaseTransport::init();
  1713.     return HXR_OK;
  1714. }
  1715. void
  1716. RTPUDPTransport::setForeignAddress(UINT32 foreignAddr, UINT16 foreignPort)
  1717. {
  1718.     m_foreignAddr = foreignAddr;
  1719.     m_foreignPort = foreignPort;
  1720.     UINT32 natTimeout = GetNATTimeout(m_pContext);
  1721.     if (!m_bIsSource && natTimeout)
  1722.     {
  1723. // Initialize keepalive object
  1724. m_keepAlive.Init(m_pScheduler, natTimeout, new KeepAliveCB(this));
  1725.     
  1726. // Do initial "poke" through the NAT
  1727. onNATKeepAlive();
  1728.     }
  1729. }
  1730. HX_RESULT RTPUDPTransport::handlePacket(IHXBuffer* pBuffer)
  1731. {
  1732.     m_keepAlive.OnActivity();
  1733.     return RTPBaseTransport::handlePacket(pBuffer);
  1734. }
  1735. void 
  1736. RTPUDPTransport::JoinMulticast(UINT32 ulAddress, UINT32 ulPort, IHXUDPSocket* pUDP)
  1737. {
  1738.     if (m_ulCurrentMulticastAddress)
  1739.     {
  1740. m_pMCastUDPSocket->LeaveMulticastGroup(m_ulCurrentMulticastAddress, HXR_INADDR_ANY);
  1741.     }
  1742.     else
  1743.     {
  1744. m_pMCastUDPSocket = pUDP;
  1745.         m_pMCastUDPSocket->AddRef();
  1746.     }
  1747.     m_pMCastUDPSocket->JoinMulticastGroup(ulAddress, HXR_INADDR_ANY);
  1748.     m_bMulticast = TRUE;
  1749.     m_ulCurrentMulticastAddress = ulAddress;
  1750.     m_ulCurrentMulticastPort = ulPort;
  1751.     if (m_pStreamHandler)
  1752.     {
  1753. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1754. ASSERT(pStreamData);
  1755. while(pStreamData)
  1756. {
  1757.     pStreamData->m_pTransportBuffer->SetMulticast();
  1758.     pStreamData = m_pStreamHandler->nextStreamData();
  1759. }
  1760.     }
  1761.     return;
  1762. }
  1763. HX_RESULT RTPUDPTransport::onNATKeepAlive()
  1764. {
  1765.     DPRINTF(D_INFO, ("RTP : onNATKeepAlive()n"));
  1766.     // Send an RTP packet with PT=0 and no payload
  1767.     IHXBuffer* pPktBuf = NULL;
  1768.     if (m_pCommonClassFactory &&
  1769. (HXR_OK == m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, (void**)&pPktBuf)))
  1770.     {
  1771. RTPPacket pkt;
  1772. pkt.version_flag = 2;
  1773. pkt.padding_flag = 0;
  1774. pkt.csrc_len = 0;
  1775. pkt.marker_flag = 0;
  1776. pkt.extension_flag = 0;
  1777. pkt.data.data = 0;
  1778. pkt.data.len = 0;
  1779. pkt.ssrc = m_pReportHandler->GetSSRC();
  1780. pkt.payload = 0;
  1781. pkt.seq_no = m_keepAliveSeq++;
  1782. pkt.timestamp =  HX_GET_TICKCOUNT() * 8; // Timestamp in 1/8000 sec
  1783. UINT32 packetLen = pkt.static_size() + pkt.data.len;
  1784. if (HXR_OK == pPktBuf->SetSize(packetLen))
  1785. {
  1786.     // Pack the data into the buffer
  1787.     pkt.pack(pPktBuf->GetBuffer(), packetLen);
  1788.     
  1789.     pPktBuf->SetSize(packetLen); // Update the packet size
  1790.     
  1791.     writePacket(pPktBuf);
  1792. }
  1793.     }
  1794.     HX_RELEASE(pPktBuf);
  1795.     return HXR_OK;
  1796. }
  1797. HX_RESULT
  1798. RTPUDPTransport::writePacket(IHXBuffer* pSendBuffer)
  1799. {    
  1800.     if (!m_pUDPSocket)
  1801.         return HXR_FAIL;
  1802.     m_keepAlive.OnActivity();
  1803.     return m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuffer);
  1804. }
  1805. /*
  1806.  * XXXMC
  1807.  * Special-case handling for PV clients
  1808.  */
  1809. HX_RESULT
  1810. RTPUDPTransport::sendPVHandshakeResponse(UINT8* pPktPayload)
  1811. {
  1812.     IHXBuffer* pPktPayloadBuff = NULL;
  1813.     m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, (void**) &pPktPayloadBuff);
  1814.     if (pPktPayloadBuff)
  1815.     {
  1816.         DPRINTF(D_INFO, ("RTP: Sending POKE PKT RESPONSEn")); 
  1817.         pPktPayloadBuff->Set((UCHAR*)pPktPayload, 8);
  1818.         writePacket(pPktPayloadBuff);
  1819.         pPktPayloadBuff->Release();
  1820.     }
  1821.     return HXR_OK;
  1822. }
  1823. HX_RESULT
  1824. RTPUDPTransport::sendPacket(BasePacket* pPacket)
  1825. {
  1826.     HX_ASSERT(m_bActive);
  1827.     
  1828.     HX_RESULT theErr;
  1829.     if (m_ulPayloadWirePacket!=0)
  1830.     {
  1831. IHXBuffer* pSendBuf = NULL;
  1832. theErr = reflectPacket(pPacket, pSendBuf);
  1833. if (HXR_OK == theErr)
  1834. {
  1835.     theErr = writePacket(pSendBuf);
  1836.     pSendBuf->Release();
  1837. }
  1838. else if (HXR_IGNORE == theErr)
  1839. {
  1840.     return HXR_OK;
  1841. }
  1842. return theErr;
  1843.     }
  1844.     
  1845.     IHXBuffer* pPacketBuf = NULL;
  1846.     
  1847.     theErr = makePacket(pPacket, pPacketBuf);
  1848.     if (HXR_OK == theErr)
  1849.     {
  1850. theErr = writePacket(pPacketBuf);
  1851. /* send SR if necessary */
  1852.      if (HXR_OK == theErr && m_pRTCPTran->m_bSendReport &&
  1853.     m_pRTCPTran->m_bSendRTCP)
  1854.      {
  1855.     m_pRTCPTran->sendSenderReport();
  1856.     m_pRTCPTran->m_bSendReport = FALSE;
  1857.     m_pRTCPTran->scheduleNextReport();
  1858.      }
  1859.     }
  1860.     HX_RELEASE(pPacketBuf);
  1861.     return theErr;
  1862. }
  1863. RTPUDPTransport::KeepAliveCB::KeepAliveCB(RTPUDPTransport* pTransport):
  1864.     m_pTransport(pTransport),
  1865.     m_lRefCount(0)
  1866. {
  1867.     if(m_pTransport)
  1868.     {
  1869. m_pTransport->AddRef();
  1870.     }
  1871. }
  1872. RTPUDPTransport::KeepAliveCB::~KeepAliveCB()
  1873. {
  1874.     HX_RELEASE(m_pTransport);
  1875. }
  1876. STDMETHODIMP
  1877. RTPUDPTransport::KeepAliveCB::QueryInterface(REFIID riid, void** ppvObj)
  1878. {
  1879.     if (IsEqualIID(riid, IID_IUnknown))
  1880.     {
  1881.         AddRef();
  1882.         *ppvObj = this;
  1883.         return HXR_OK;
  1884.     }
  1885.     else if (IsEqualIID(riid, IID_IHXCallback))
  1886.     {
  1887.         AddRef();
  1888.         *ppvObj = (IHXCallback*)this;
  1889.         return HXR_OK;
  1890.     }
  1891.     *ppvObj = NULL;
  1892.     return HXR_NOINTERFACE;
  1893. }
  1894. STDMETHODIMP_(UINT32)
  1895. RTPUDPTransport::KeepAliveCB::AddRef()
  1896. {
  1897.     return InterlockedIncrement(&m_lRefCount);
  1898. }
  1899. STDMETHODIMP_(UINT32)
  1900. RTPUDPTransport::KeepAliveCB::Release()
  1901. {
  1902.     if(InterlockedDecrement(&m_lRefCount) > 0)
  1903.     {
  1904. return m_lRefCount;
  1905.     }
  1906.     delete this;
  1907.     return 0;
  1908. }
  1909. STDMETHODIMP
  1910. RTPUDPTransport::KeepAliveCB::Func()
  1911. {
  1912.     if (m_pTransport)
  1913.     {
  1914. m_pTransport->onNATKeepAlive();
  1915.     }
  1916.     return HXR_OK;
  1917. }
  1918. /*
  1919.  * RTP TCP
  1920.  */
  1921. RTPTCPTransport::RTPTCPTransport(BOOL bIsSource)
  1922.     : RTPBaseTransport(bIsSource)
  1923.     , m_pTCPSocket(0)
  1924.     , m_tcpInterleave(0)
  1925.     m_wrapSequenceNumber = DEFAULT_WRAP_SEQ_NO;
  1926. }
  1927. RTPTCPTransport::~RTPTCPTransport()
  1928. {
  1929.     HX_RELEASE(m_pTCPSocket);
  1930. }
  1931. void
  1932. RTPTCPTransport::Done()
  1933. {
  1934.     RTPBaseTransport::Done();
  1935. }
  1936. RTSPTransportTypeEnum
  1937. RTPTCPTransport::tag()
  1938. {
  1939.     return RTSP_TR_RTP_TCP;
  1940. }
  1941. HX_RESULT
  1942. RTPTCPTransport::init(IUnknown* pContext, 
  1943.       IHXTCPSocket* pSocket,
  1944.       IHXRTSPTransportResponse* pResp)
  1945. {
  1946.     m_pTCPSocket = pSocket;
  1947.     m_pTCPSocket->AddRef();
  1948.     m_pResp = pResp;
  1949.     m_pResp->AddRef();
  1950.     /* Set DiffServ Code Point */
  1951.     IHXSetSocketOption* pOpt = NULL;
  1952.     if (SUCCEEDED(m_pTCPSocket->QueryInterface(IID_IHXSetSocketOption, (void**)&pOpt)))
  1953.     {
  1954. IHXQoSDiffServConfigurator* pCfg = NULL;
  1955. if (SUCCEEDED(pContext->QueryInterface(IID_IHXQoSDiffServConfigurator, (void**)&pCfg)))
  1956. {
  1957.     pCfg->ConfigureSocket(pOpt, HX_QOS_DIFFSERV_CLASS_MEDIA);
  1958.     pCfg->Release();
  1959.     pCfg = NULL;
  1960. }
  1961. pOpt->Release();
  1962. pOpt = NULL;
  1963.     }
  1964.     HX_RESULT hresult = Init(pContext);
  1965.     if (HXR_OK != hresult)
  1966.     {
  1967. return hresult;
  1968.     }
  1969.     RTPBaseTransport::init();
  1970.     return HXR_OK;
  1971. }
  1972. HX_RESULT
  1973. RTPTCPTransport::sendPacket(BasePacket* pPacket)
  1974. {
  1975.     HX_ASSERT(m_bActive);
  1976.     HX_RESULT theErr;
  1977.     if (m_ulPayloadWirePacket!=0)
  1978.     {
  1979. IHXBuffer* pSendBuf = NULL;
  1980. theErr = reflectPacket(pPacket, pSendBuf);
  1981. if (HXR_OK == theErr)
  1982. {
  1983.     theErr = writePacket(pSendBuf);
  1984.     pSendBuf->Release();
  1985. }
  1986. else if (HXR_IGNORE == theErr)
  1987. {
  1988.     return HXR_OK;
  1989. }
  1990. return theErr;
  1991.     }
  1992.     IHXBuffer* pPacketBuf = NULL;
  1993.     
  1994.     theErr = makePacket(pPacket, pPacketBuf);
  1995.     if (HXR_OK == theErr)
  1996.     {
  1997. theErr = writePacket(pPacketBuf);
  1998. /* send SR if necessary */
  1999.      if (HXR_OK == theErr && m_pRTCPTran->m_bSendReport && 
  2000.     m_pRTCPTran->m_bSendRTCP)
  2001.      {
  2002.     m_pRTCPTran->sendSenderReport();
  2003.     m_pRTCPTran->m_bSendReport = FALSE;
  2004.     m_pRTCPTran->scheduleNextReport();
  2005.      }
  2006.     }
  2007.     HX_RELEASE(pPacketBuf);
  2008.     return theErr;
  2009. }
  2010. HX_RESULT
  2011. RTPTCPTransport::writePacket(IHXBuffer* pBuf)
  2012. {
  2013.     if (!m_pTCPSocket)
  2014.         return HXR_FAIL;
  2015.     // need to put $00[datalen] in front of packet data
  2016.     UINT32 dataLen = pBuf->GetSize();
  2017.     if(dataLen > 0xffff)
  2018.     {
  2019. return HXR_FAIL;
  2020.     }
  2021.     //XXXTDM: always true, m_tcpInteleave is signed (why?)
  2022.     //HX_ASSERT(0xFF != m_tcpInterleave);
  2023.     IHXBuffer* pHeader = NULL;
  2024.     m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
  2025.                                           (void**)&pHeader);
  2026.     BYTE* pHeaderData;
  2027.     if(!pHeader)
  2028.     {
  2029.         return HXR_OUTOFMEMORY;
  2030.     }
  2031.     pHeader->SetSize(4);
  2032.     pHeaderData = pHeader->GetBuffer();
  2033.     pHeaderData[0] = '$';
  2034.     pHeaderData[1] = m_tcpInterleave;
  2035.     putshort(&pHeaderData[2], (UINT16)dataLen);
  2036.     HX_RESULT rc;
  2037.     rc = m_pTCPSocket->Write(pHeader);
  2038.     if (SUCCEEDED(rc))
  2039.     {
  2040.         rc = m_pTCPSocket->Write(pBuf);
  2041.     }
  2042.     if(rc)
  2043.     {
  2044.         m_pResp->OnProtocolError(HXR_NET_SOCKET_INVALID);
  2045.     }
  2046.     pHeader->Release();
  2047.     return rc;
  2048. }
  2049. /******************************************************************************
  2050. *   RTCP RTCP RTCP RTCP RTCP
  2051. ******************************************************************************/
  2052. RTCPBaseTransport::RTCPBaseTransport(BOOL bIsSource):
  2053.     RTSPTransport(bIsSource),
  2054.     m_lRefCount(0),
  2055.     m_bCallbackPending(FALSE),
  2056.     m_pReportCallback(0),
  2057.     m_reportTimeoutID(0),
  2058.     m_bSchedulerStarted(FALSE),
  2059.     m_bSendRTCP(TRUE),
  2060.     m_bSendBye(FALSE),
  2061.     m_bSendReport(FALSE),
  2062.     m_pcCNAME(NULL),
  2063.     m_pReportHandler(NULL),
  2064.     m_pDataTransport(NULL),
  2065.     m_pTSConverter(NULL),
  2066.     m_streamNumber(0xffff),
  2067.     m_pSignalBus(NULL),
  2068.     m_pQoSSignal_RR(NULL),
  2069.     m_pQoSSignal_APP(NULL),
  2070.     m_pSessionId(NULL),
  2071.     m_bSSRCDetermined(FALSE),
  2072.     m_ulSSRCDetermined(0)
  2073. {
  2074. }
  2075. RTCPBaseTransport::~RTCPBaseTransport()
  2076. {
  2077.     HX_DELETE(m_pTSConverter);
  2078. }
  2079. STDMETHODIMP
  2080. RTCPBaseTransport::QueryInterface(REFIID riid, void** ppvObj)
  2081. {
  2082.     if (IsEqualIID(riid, IID_IUnknown))
  2083.     {
  2084.         AddRef();
  2085.         *ppvObj = this;
  2086.         return HXR_OK;
  2087.     }
  2088.     else if (IsEqualIID(riid, IID_IHXQoSSignalSourceResponse))
  2089.     {
  2090.         AddRef();
  2091.         *ppvObj = (IHXQoSSignalSourceResponse*)this;
  2092.         return HXR_OK;
  2093.     }
  2094.     *ppvObj = NULL;
  2095.     return HXR_NOINTERFACE;
  2096. }
  2097. STDMETHODIMP_(UINT32)
  2098. RTCPBaseTransport::AddRef()
  2099. {
  2100.     return InterlockedIncrement(&m_lRefCount);
  2101. }
  2102. STDMETHODIMP_(UINT32)
  2103. RTCPBaseTransport::Release()
  2104. {
  2105.     if(InterlockedDecrement(&m_lRefCount) > 0)
  2106.     {
  2107. return m_lRefCount;
  2108.     }
  2109.     delete this;
  2110.     return 0;
  2111. }
  2112. void
  2113. RTCPBaseTransport::Done()
  2114. {
  2115.     stopScheduler();
  2116.     HX_RELEASE(m_pPacketFilter);
  2117.     HX_VECTOR_DELETE(m_pcCNAME);
  2118.     HX_DELETE(m_pReportHandler);
  2119.     HX_RELEASE(m_pQoSSignal_RR);
  2120.     HX_RELEASE(m_pQoSSignal_APP);
  2121.     HX_RELEASE(m_pSignalBus);
  2122.     HX_RELEASE(m_pSessionId);
  2123. }
  2124. HX_RESULT
  2125. RTCPBaseTransport::init()
  2126. {
  2127.     HX_ASSERT(!m_pReportCallback);
  2128.     HX_ASSERT(!m_pcCNAME);
  2129.     
  2130.     m_pReportCallback = new ReportCallback(this);
  2131.     if(!m_pReportCallback)
  2132.     {
  2133.         return HXR_OUTOFMEMORY;
  2134.     }
  2135.     m_pReportCallback->AddRef();
  2136.     char cname[16] = {0}; /* Flawfinder: ignore */
  2137.     itoa(random32(HX_GET_TICKCOUNT()), cname, 10);    
  2138.     m_pcCNAME = (BYTE*)new_string(cname);
  2139.     HX_ASSERT(m_pcCNAME);
  2140.     return HXR_OK;
  2141. }
  2142. void 
  2143. RTCPBaseTransport::addStreamInfo (RTSPStreamInfo* pStreamInfo,
  2144.   UINT32 ulBufferDepth)
  2145. {
  2146.     UINT32 ulInvalidRate = (UINT32)-1;
  2147.     UINT32 ulAvgBitRate = pStreamInfo->m_ulAvgBitRate;
  2148.     UINT32 ulRRBitRate = pStreamInfo->m_ulRtpRRBitRate;
  2149.     UINT32 ulRSBitRate = pStreamInfo->m_ulRtpRSBitRate;
  2150.     BOOL   bUseRFC1889MinTime = FALSE;
  2151.     if (!ulAvgBitRate)
  2152.     {
  2153. // We don't know the average bitrate.
  2154. // Make something up
  2155. ulAvgBitRate = 20000;
  2156.     }
  2157.     else
  2158.     {
  2159. UINT32 ulRTCPBw = ulAvgBitRate / 20; // 5% of AvgBitRate
  2160. if ((ulRRBitRate == ulInvalidRate) &&
  2161.     (ulRSBitRate != ulInvalidRate) &&
  2162.     (ulRTCPBw > ulRSBitRate))
  2163. {
  2164.     ulRRBitRate = ulRTCPBw - ulRSBitRate;
  2165. }
  2166. else if ((ulRRBitRate != ulInvalidRate) &&
  2167.  (ulRSBitRate == ulInvalidRate) &&
  2168.  (ulRTCPBw > ulRRBitRate))
  2169. {
  2170.     ulRSBitRate = ulRTCPBw - ulRRBitRate;
  2171. }
  2172.     }
  2173.     if ((ulRRBitRate == ulInvalidRate) ||
  2174. (ulRSBitRate == ulInvalidRate))
  2175.     {
  2176. // If one of the bitrates is still
  2177. // invalid at this point we just
  2178. // default to the RFC 1889 behavior.
  2179. // RS = 1.25% of the average bitrate
  2180. // RR = 3.75% of the average bitrate
  2181. bUseRFC1889MinTime = TRUE;
  2182. m_bSendRTCP = TRUE;
  2183. ulRSBitRate = ulAvgBitRate / 80; // 1.25%
  2184. ulRRBitRate = ((ulAvgBitRate / 80) * 3 +
  2185.        ((ulAvgBitRate % 80) * 3) / 80); // 3.75%
  2186.     }
  2187.     else if (ulRRBitRate == 0)
  2188.     {
  2189. // We have been told not
  2190. // to send RTCP reports
  2191. m_bSendRTCP = FALSE;
  2192.     }
  2193.     if (m_pReportHandler)
  2194.     {
  2195. // Get the minimum RTCP report interval
  2196. UINT32 ulMinIntervalMs = (bUseRFC1889MinTime) ? 5000 : 1;
  2197. // Pass the report interval parameters to 
  2198. // the report handler
  2199. m_pReportHandler->SetRTCPIntervalParams(ulRSBitRate, ulRRBitRate,
  2200. ulMinIntervalMs);
  2201.     }
  2202. }
  2203. void
  2204. RTCPBaseTransport::setSSRC(UINT32 ulSSRC)
  2205. {
  2206.     m_bSSRCDetermined = TRUE;
  2207.     m_ulSSRCDetermined = ulSSRC;
  2208. }
  2209. void
  2210. RTCPBaseTransport::setSessionID(const char* pSessionID)
  2211. {
  2212.     /* cache the session id for use in retrieving signal bus*/
  2213.     if(pSessionID && (SUCCEEDED(m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
  2214.       (void**)&m_pSessionId))))
  2215.     {
  2216. m_pSessionId->Set((UCHAR*)pSessionID, 
  2217.   strlen(pSessionID)+1);
  2218. IHXQoSSignalSource* pSignalSrc = NULL;
  2219. if (m_pSessionId && SUCCEEDED(m_pContext->QueryInterface(IID_IHXQoSSignalSource,
  2220.  (void**) &pSignalSrc)))
  2221. {
  2222.     pSignalSrc->GetSignalBus(m_pSessionId, (IHXQoSSignalSourceResponse*)this);
  2223.     HX_RELEASE(pSignalSrc);
  2224. }
  2225. else
  2226. {
  2227.     m_pSignalBus = NULL;
  2228. }
  2229.     }
  2230. }
  2231. STDMETHODIMP
  2232. RTCPBaseTransport::SignalBusReady (HX_RESULT hResult, IHXQoSSignalBus* pBus, 
  2233.    IHXBuffer* pSessionId)
  2234. {
  2235.     if (FAILED(hResult))
  2236.     {
  2237. HX_ASSERT(0);
  2238. return HXR_OK;
  2239.     }
  2240.     m_pSignalBus = pBus;
  2241.     m_pSignalBus->AddRef();
  2242.     if (m_pDataTransport)
  2243.     {
  2244.         if (FAILED(m_pSignalBus->QueryInterface(IID_IHXQoSTransportAdaptationInfo,
  2245.                                                 (void**)&m_pDataTransport->m_pQoSInfo)))
  2246.         {
  2247.             m_pDataTransport->m_pQoSInfo = NULL;
  2248.         }
  2249.     }
  2250.     else
  2251.     {
  2252.         HX_ASSERT(0);
  2253.     }
  2254.     if (SUCCEEDED(m_pCommonClassFactory->CreateInstance(CLSID_IHXQoSSignal,
  2255. (void**)&m_pQoSSignal_RR)))
  2256.     {
  2257. m_pQoSSignal_RR->SetId(MAKE_HX_QOS_SIGNAL_ID(HX_QOS_SIGNAL_LAYER_FRAMING_TRANSPORT,
  2258.   HX_QOS_SIGNAL_RELEVANCE_METRIC,
  2259.   HX_QOS_SIGNAL_RTCP_RR));
  2260.     }
  2261.     else
  2262.     {
  2263. HX_ASSERT(0);
  2264. m_pQoSSignal_RR = NULL;
  2265.     }
  2266.     if (SUCCEEDED(m_pCommonClassFactory->CreateInstance(CLSID_IHXQoSSignal,
  2267. (void**)&m_pQoSSignal_APP)))
  2268.     {
  2269.         m_pQoSSignal_APP->SetId(MAKE_HX_QOS_SIGNAL_ID(HX_QOS_SIGNAL_LAYER_FRAMING_TRANSPORT,
  2270.    HX_QOS_SIGNAL_RELEVANCE_METRIC,
  2271.    HX_QOS_SIGNAL_COMMON_BUFSTATE));
  2272.     }
  2273.     else
  2274.     {
  2275. HX_ASSERT(0);
  2276. m_pQoSSignal_APP = NULL;
  2277.     }
  2278.     return HXR_OK;
  2279. }
  2280. HX_RESULT 
  2281. RTCPBaseTransport::SetTSConverter(CHXTimestampConverter::ConversionFactors conversionFactors)
  2282. {
  2283.     HX_DELETE(m_pTSConverter);
  2284.     m_pTSConverter = new CHXTimestampConverter(conversionFactors);
  2285.     return m_pTSConverter ? HXR_OK : HXR_OUTOFMEMORY;
  2286. }
  2287. HX_RESULT
  2288. RTCPBaseTransport::startScheduler()
  2289. {
  2290.     if(!m_bSchedulerStarted && m_bSendRTCP)
  2291.     {
  2292. HX_ASSERT(!m_bCallbackPending);
  2293. m_bSchedulerStarted = TRUE;
  2294. if (!m_bMulticast)
  2295. {
  2296.     // we wanna send the report right away!
  2297.     m_bSendReport = TRUE;
  2298. }
  2299. else
  2300. {    
  2301.     if (!m_bCallbackPending)
  2302.     {
  2303. scheduleNextReport();
  2304.     }
  2305. }
  2306.     }
  2307.     return HXR_OK;
  2308. }
  2309. HX_RESULT
  2310. RTCPBaseTransport::stopScheduler()
  2311. {
  2312.     if(m_bCallbackPending)
  2313.     {
  2314. HX_ASSERT(m_pScheduler);
  2315. m_pScheduler->Remove(m_reportTimeoutID);
  2316. m_bCallbackPending = FALSE;
  2317.     }
  2318.     HX_RELEASE(m_pReportCallback);
  2319.     return HXR_OK;
  2320. }
  2321. void
  2322. RTCPBaseTransport::scheduleNextReport()
  2323. {
  2324.     if (m_bSendRTCP)
  2325.     {
  2326. HX_ASSERT(!m_bSendReport);
  2327. HX_ASSERT(!m_bCallbackPending);
  2328. HX_ASSERT(m_pReportCallback);
  2329. HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
  2330. Timeval tvNow((INT32)rmatv.tv_sec, (INT32)rmatv.tv_usec);
  2331. tvNow += Timeval(m_pReportHandler->GetRTCPInterval());
  2332. rmatv.tv_sec = tvNow.tv_sec;
  2333. rmatv.tv_usec = tvNow.tv_usec;
  2334. m_reportTimeoutID = 
  2335.     m_pScheduler->AbsoluteEnter(m_pReportCallback, rmatv);
  2336. m_bCallbackPending = TRUE;
  2337.     }
  2338. }
  2339. /*
  2340. *   we don't have a table of sender or receivers because we don't yet 
  2341. *   support multicast.  i.e. only one sender, one receiver
  2342. */
  2343. HX_RESULT
  2344. RTCPBaseTransport::handlePacket(IHXBuffer* pBuffer)
  2345. {
  2346.     // we need to deal with a compund packet
  2347.     RTCPUnPacker unpacker;
  2348. //{FILE* f1 = ::fopen("c:\temp\all.txt", "a+"); ::fprintf(f1, "this: %p RTCPTransport::handlePacket(): ", this);::fclose(f1);}      
  2349.     if (HXR_OK != unpacker.UnPack(pBuffer))
  2350.     {
  2351. // failed...don't do anything more...still ok to return HXR_OK;
  2352. return HXR_OK;
  2353.     }
  2354.     /* update */
  2355.     m_pReportHandler->UpdateAvgRTCPSize(pBuffer->GetSize());
  2356.     HX_RESULT theErr = HXR_OK;
  2357.     RTCPPacket* pPkt = NULL;
  2358.     HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
  2359.     UINT32 ulNow = rmatv.tv_sec * 1000 + rmatv.tv_usec / 1000;
  2360.     // for EOS support
  2361.     BOOL bBye = FALSE;
  2362.     APPItem* pAppPkt = NULL;
  2363.     while (HXR_OK == unpacker.Get(pPkt))
  2364.     {
  2365. //{FILE* f1 = ::fopen("c:\temp\all.txt", "a+"); ::fprintf(f1, "%un", pPkt->packet_type);::fclose(f1);}  
  2366.         if (m_bIsSource || (m_bSSRCDetermined && m_ulSSRCDetermined == pPkt->sr_ssrc))
  2367.         {    
  2368.     // deal with it!
  2369.          switch(pPkt->packet_type)
  2370.          {
  2371.         case RTCP_SR:
  2372.         {
  2373.          DPRINTF(D_INFO, ("RTCP: SenderReport receivedn"));
  2374.     m_pReportHandler->OnRTCPReceive(pPkt, ulNow);
  2375.     m_pDataTransport->handleRTCPSync(NTPTime(pPkt->ntp_sec, 
  2376.      pPkt->ntp_frac),
  2377.      pPkt->rtp_ts);
  2378.         }
  2379.         break;
  2380.     
  2381.         case RTCP_RR:
  2382.         {
  2383.          DPRINTF(D_INFO, ("RTCP: ReceiverReport receivedn"));
  2384.     m_pReportHandler->OnRTCPReceive(pPkt, ulNow);
  2385.     
  2386.     IHXBuffer* pTmp = NULL;
  2387.     if((m_pSignalBus) && SUCCEEDED(m_pCommonClassFactory->
  2388.            CreateInstance(CLSID_IHXBuffer,
  2389.           (void**)&pTmp)))
  2390.     {
  2391.         for (UINT32 i = 0; i < pPkt->count; i++)
  2392.         {
  2393.     if (pPkt->rr_data[i].ssrc == m_pReportHandler->GetSSRC())
  2394.     {
  2395.         pTmp->SetSize(sizeof(ReceptionReport));
  2396.         ReceptionReport* pRR = (ReceptionReport*)pTmp->GetBuffer();
  2397.         HX_ASSERT(pRR);
  2398.         //replace the ssrc with the server specific stream number
  2399.         pRR->ssrc     = m_streamNumber;
  2400.         //copy in the remaining receiver report data
  2401.         pRR->fraction = pPkt->rr_data[i].fraction;
  2402.         pRR->lost     = pPkt->rr_data[i].lost;
  2403.         pRR->last_seq = pPkt->rr_data[i].last_seq;
  2404.         pRR->lsr      = (m_pDataTransport) ? 
  2405.     m_pDataTransport->MapLSR(pPkt->rr_data[i].lsr) : 0;
  2406.         pRR->dlsr     = pPkt->rr_data[i].dlsr;
  2407. if (m_pDataTransport && m_pDataTransport->m_pQoSInfo)
  2408. {
  2409.     m_pDataTransport->m_pQoSInfo->SetPacketLoss(pRR->lost);
  2410. }
  2411.         m_pQoSSignal_RR->SetValue(pTmp);
  2412.         m_pSignalBus->Send(m_pQoSSignal_RR);
  2413.       }
  2414.         }
  2415.     }
  2416.     HX_RELEASE(pTmp);
  2417.         }
  2418.         break;
  2419.     
  2420.         case RTCP_SDES:
  2421.         {
  2422.          DPRINTF(D_INFO, ("RTCP: SDESReport receivedn"));
  2423.          m_pReportHandler->OnRTCPReceive(pPkt, ulNow);
  2424.         }
  2425.         break;
  2426.     
  2427.         case RTCP_BYE:
  2428.         {
  2429.          DPRINTF(D_INFO, ("RTCP: BYE receivedn"));
  2430.     m_pReportHandler->OnRTCPReceive(pPkt, ulNow);
  2431.     bBye = TRUE;
  2432.         }
  2433.         break;
  2434.     
  2435.         case RTCP_APP:
  2436.         {
  2437.          DPRINTF(D_INFO, ("RTCP: APP receivedn"));
  2438.     // make sure this APP is from RS.
  2439.     // Hmmm...This is a security risk...Anyone can send APP pkt 
  2440.     // with "RNWK"...
  2441.     if ((0 != strncmp((const char*)pPkt->app_name, "RNWK", 4)) &&
  2442.         (0 != strncmp((const char*)pPkt->app_name, "HELX", 4)))
  2443.     {
  2444.         // unknown APP, ignore it.
  2445.         break;
  2446.     }
  2447.     if (!(pPkt->m_pAPPItems))
  2448.     {
  2449.         break;
  2450.     }
  2451.          HX_ASSERT(1 == pPkt->count);
  2452.          pAppPkt = new APPItem();
  2453.                     if(!pAppPkt)
  2454.                     {
  2455.                         theErr = HXR_OUTOFMEMORY;
  2456.                         break;
  2457.                     }
  2458.     if ((pPkt->m_pAPPItems[0]).app_type == APP_BUFINFO)
  2459.     {
  2460.         IHXBuffer* pTmp = NULL;
  2461.         if((m_pSignalBus) && SUCCEEDED(m_pCommonClassFactory->
  2462.        CreateInstance(CLSID_IHXBuffer,
  2463.       (void**)&pTmp)))
  2464.         {
  2465.     // pTmp->Set((UCHAR*)(&pPkt->m_pAPPItems[0]), sizeof(APPItem));
  2466.                             pTmp->SetSize(sizeof(BufferMetricsSignal));
  2467.               BufferMetricsSignal* pbufSig = 
  2468.           (BufferMetricsSignal*)pTmp->GetBuffer();
  2469.     // The correct mapping from SSRC to stream number relies on the port multiplexing
  2470.     // used by the current implementation. If we use SSRC-based multiplexing, we will
  2471.     // need to take a look again at this mapping.                        
  2472.                             pbufSig->m_ulStreamNumber = m_streamNumber;
  2473.                             pbufSig->m_ulLowTimestamp = pPkt->m_pAPPItems[0].lowest_timestamp;
  2474.               pbufSig->m_ulHighTimestamp = pPkt->m_pAPPItems[0].highest_timestamp;
  2475.               pbufSig->m_ulBytes = pPkt->m_pAPPItems[0].bytes_buffered;
  2476.                             m_pQoSSignal_APP->SetValue(pTmp);
  2477.               m_pSignalBus->Send(m_pQoSSignal_APP);
  2478.              HX_RELEASE(pTmp);
  2479.         }
  2480.     }
  2481.     else
  2482.     {
  2483.         memcpy(pAppPkt, &pPkt->m_pAPPItems[0], sizeof(APPItem)); /* Flawfinder: ignore */
  2484.     }
  2485.         }
  2486.         break;
  2487.     
  2488.         default:
  2489.         {
  2490.          DPRINTF(D_INFO, ("RTCP: Don't know this pkt typen"));     
  2491.         }
  2492.          }
  2493.         }
  2494.      // Im responsible of freeing the pkt
  2495.      HX_DELETE(pPkt);
  2496.     }
  2497.     if ((bBye) && (!m_bIsSource))
  2498.     {
  2499. HX_ASSERT(m_streamNumber == m_pDataTransport->m_streamNumber);
  2500. RTSPTransportBuffer* pTransportBuffer = 
  2501.     m_pDataTransport->getTransportBuffer(m_pDataTransport->m_streamNumber);
  2502. if (pTransportBuffer)
  2503. {
  2504.     if (pAppPkt && (APP_EOS == pAppPkt->app_type))
  2505.     {
  2506. pTransportBuffer->SetEndPacket(pAppPkt->seq_no,
  2507.        0,
  2508.        pAppPkt->packet_sent,
  2509.        pAppPkt->timestamp);
  2510.     }
  2511.     else
  2512.     {
  2513. pTransportBuffer->InformSourceStopped();
  2514.     }
  2515. }
  2516. else
  2517. {
  2518.     HX_ASSERT(!"can't find the transport buffer");
  2519.     theErr = HXR_FAIL;
  2520. }
  2521.     }
  2522.     HX_DELETE(pAppPkt);
  2523.     return theErr;
  2524. }
  2525. /*
  2526. *   
  2527. *
  2528. */
  2529. HX_RESULT
  2530. RTCPBaseTransport::makeBye(REF(IHXBuffer*) pSendBuf)
  2531. {
  2532.     HX_ASSERT(m_pDataTransport->m_streamNumber == m_streamNumber);    
  2533.     HX_ASSERT(m_bSendBye);
  2534.     // consider it sent...
  2535.     m_bSendBye = FALSE;
  2536.     
  2537.     HX_RESULT theErr = HXR_FAIL;
  2538. //    IHXBuffer* pSendBuf = NULL;
  2539.     RTCPPacket* pPktSDES = NULL;
  2540.     RTCPPacket* pPktBYE  = NULL;
  2541.     RTCPPacket* pPktAPP  = NULL;
  2542.     HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
  2543.     UINT32 ulNow = rmatv.tv_sec*1000 + rmatv.tv_usec/1000;
  2544.     Timeval tvNow((INT32) rmatv.tv_sec, (INT32)rmatv.tv_usec);
  2545.     
  2546.     RTCPPacker packer;
  2547.     
  2548.     RTCPPacket* pPktR = new RTCPPacket();
  2549.     if(!pPktR)
  2550.     {
  2551.         theErr = HXR_OUTOFMEMORY;
  2552. goto bail;
  2553.     }
  2554.     if (m_bIsSource)
  2555.     {
  2556. theErr = m_pReportHandler->MakeSR(pPktR, tvNow);
  2557.     }
  2558.     else
  2559.     {
  2560. theErr = m_pReportHandler->MakeRR(pPktR, ulNow);
  2561.     }
  2562.     if (HXR_OK != theErr)
  2563.     {
  2564. // no SR/RR, no RTCP
  2565. goto bail;
  2566.     }
  2567.     pPktSDES = new RTCPPacket();
  2568.     if(!pPktSDES)
  2569.     {
  2570.         theErr = HXR_OUTOFMEMORY;
  2571. goto bail;
  2572.     }
  2573.     theErr = m_pReportHandler->MakeSDES(pPktSDES, m_pcCNAME);
  2574.     if (HXR_OK != theErr)
  2575.     {
  2576. goto bail;
  2577.     }
  2578.     pPktBYE = new RTCPPacket();
  2579.     if(!pPktBYE)
  2580.     {
  2581.         theErr = HXR_OUTOFMEMORY;
  2582. goto bail;
  2583.     }
  2584.     theErr = m_pReportHandler->MakeBye(pPktBYE);
  2585.     if (HXR_OK != theErr)
  2586.     {
  2587. goto bail;
  2588.     }
  2589.     // if it is source, we need to make EOS pkt
  2590.     if (m_bIsSource)
  2591.     {
  2592.      pPktAPP = new RTCPPacket();
  2593.         if(!pPktAPP)
  2594.         {
  2595.             theErr = HXR_OUTOFMEMORY;
  2596.     goto bail;
  2597.         }
  2598.      theErr = m_pReportHandler->MakeEOSApp(pPktAPP);
  2599.      if (HXR_OK != theErr)
  2600.      {
  2601.     goto bail;
  2602.      }   
  2603.     }
  2604.     // pack them up!
  2605.     theErr = m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
  2606.    (void**)&pSendBuf);
  2607.     if (HXR_OK != theErr)
  2608.     {
  2609. HX_ASSERT(!pSendBuf);
  2610. goto bail;
  2611.     }
  2612.     packer.Set(pPktR);
  2613.     packer.Set(pPktSDES);
  2614.     packer.Set(pPktBYE);
  2615.     if (m_bIsSource)
  2616.     {
  2617. HX_ASSERT(pPktAPP);
  2618. packer.Set(pPktAPP);
  2619.     }
  2620.     theErr = packer.Pack(pSendBuf);
  2621.            
  2622.     if (HXR_OK != theErr)
  2623.     {
  2624. HX_ASSERT(FALSE && "failed to create Report/BYE RTCP pkt");
  2625. goto bail;
  2626.     }
  2627. bail:
  2628.     HX_DELETE(pPktR);
  2629.     HX_DELETE(pPktSDES);
  2630.     HX_DELETE(pPktBYE);
  2631.     HX_DELETE(pPktAPP);
  2632. //    HX_RELEASE(pSendBuf);
  2633.     return theErr;
  2634. }
  2635. HX_RESULT
  2636. RTCPBaseTransport::makeSenderReport(REF(IHXBuffer*) pSendBuf)
  2637. {
  2638.     // create SR
  2639.     // create SDES
  2640.     // create compound RTCP
  2641.     // send
  2642.     // no reception report on the server
  2643.     // if no pkt has been sent, wait!
  2644.     HX_ASSERT(m_pDataTransport->m_streamNumber == m_streamNumber);    
  2645.     RTSPStreamData* pStreamData = 
  2646.     m_pDataTransport->m_pStreamHandler->getStreamData(m_pDataTransport->m_streamNumber);
  2647.     
  2648.     if(!pStreamData || !pStreamData->m_packetSent)
  2649.     {
  2650. return HXR_FAIL;
  2651.     }
  2652.     HX_ASSERT(pStreamData->m_streamNumber == m_streamNumber);
  2653.     HX_RESULT theErr = HXR_FAIL;
  2654. //    IHXBuffer* pSendBuf = NULL;
  2655.     RTCPPacket* pPktSDES = NULL;
  2656.     HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
  2657.     UINT32 ulNow = rmatv.tv_sec*1000 + rmatv.tv_usec/1000;
  2658.     Timeval tvNow((INT32) rmatv.tv_sec, (INT32)rmatv.tv_usec);
  2659.     RTCPPacker packer;
  2660.     RTCPPacket* pPktSR = new RTCPPacket();
  2661.     if(!pPktSR)
  2662.     {
  2663.         theErr = HXR_OUTOFMEMORY;
  2664. goto bail;
  2665.     }
  2666.     theErr = m_pReportHandler->MakeSR(pPktSR, tvNow);
  2667.     if (HXR_OK != theErr)
  2668.     {
  2669. goto bail;
  2670.     }
  2671.     
  2672.     pPktSDES = new RTCPPacket();
  2673.     if(!pPktSDES)
  2674.     {
  2675.         theErr = HXR_OUTOFMEMORY;
  2676. goto bail;
  2677.     }
  2678.     theErr = m_pReportHandler->MakeSDES(pPktSDES, m_pcCNAME);
  2679.     if (HXR_OK != theErr)
  2680.     {
  2681. goto bail;
  2682.     }
  2683.     
  2684.     // pack them up!
  2685.     theErr = m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
  2686.    (void**)&pSendBuf);
  2687.     if (HXR_OK != theErr)
  2688.     {
  2689. HX_ASSERT(!pSendBuf);
  2690. goto bail;
  2691.     }
  2692.            
  2693.     packer.Set(pPktSR);
  2694.     packer.Set(pPktSDES);
  2695.     theErr = packer.Pack(pSendBuf);
  2696.     if (HXR_OK != theErr)
  2697.     {
  2698. HX_ASSERT(FALSE && "failed to create SR/SDES RTCP pkt");
  2699. goto bail;
  2700.     }
  2701. //    theErr = m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuf);
  2702.     m_pReportHandler->UpdateAvgRTCPSize(pSendBuf->GetSize());
  2703.     m_bSendBye = TRUE;
  2704. bail:
  2705.     HX_DELETE(pPktSR);
  2706.     HX_DELETE(pPktSDES);
  2707. //    HX_RELEASE(pSendBuf);
  2708.     return theErr;
  2709. }
  2710. HX_RESULT
  2711. RTCPBaseTransport::makeReceiverReport(REF(IHXBuffer*) pSendBuf)
  2712. {
  2713.     // create RR
  2714.     // create SDES
  2715.     // create BufferInfo
  2716.     // create compund RTCP
  2717.     // send
  2718.     HX_ASSERT(m_pDataTransport->m_streamNumber == m_streamNumber);    
  2719.     HX_RESULT theErr = HXR_FAIL;
  2720. //    IHXBuffer* pSendBuf = NULL;
  2721.     RTCPPacket* pPktSDES = NULL;
  2722.     RTCPPacket* pPktBufInfo = NULL;
  2723.     HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
  2724.     UINT32 ulNow = rmatv.tv_sec*1000 + rmatv.tv_usec/1000;
  2725.     INT64 llLowTS = 0;
  2726.     INT64 llHighTS = 0;
  2727.     UINT32 ulBytesBuffered = 0;
  2728.     BOOL bDone = FALSE;
  2729.     RTCPPacker packer;
  2730.     RTCPPacket* pPktRR = new RTCPPacket();
  2731.     if(!pPktRR)
  2732.     {
  2733. theErr = HXR_OUTOFMEMORY;
  2734. goto bail;
  2735.     }
  2736.     theErr = m_pReportHandler->MakeRR(pPktRR, ulNow);
  2737.     if (HXR_OK != theErr)
  2738.     {
  2739. goto bail;
  2740.     }
  2741.     
  2742.     pPktSDES = new RTCPPacket();
  2743.     if(!pPktSDES)
  2744.     {
  2745. theErr = HXR_OUTOFMEMORY;
  2746. goto bail;
  2747.     }
  2748.     theErr = m_pReportHandler->MakeSDES(pPktSDES, m_pcCNAME);
  2749.     if (HXR_OK != theErr)
  2750.     {
  2751. goto bail;
  2752.     }
  2753.     pPktBufInfo = new RTCPPacket();
  2754.     
  2755.     // Get buffer info from m_pSrcBufferStats
  2756.     if (!m_pSrcBufferStats || !m_pReportHandler ||
  2757. HXR_OK != m_pSrcBufferStats->GetTotalBuffering(m_streamNumber, 
  2758.        llLowTS, llHighTS,
  2759.        ulBytesBuffered,
  2760.        bDone) ||
  2761. HXR_OK != m_pReportHandler->MakeBufInfoApp(pPktBufInfo, 
  2762.    INT64_TO_UINT32(llLowTS), 
  2763.    INT64_TO_UINT32(llHighTS),
  2764.    ulBytesBuffered))
  2765.     {
  2766. // If we failed for some reason,
  2767. // just delete the packet so that
  2768. // it doesn't get included in the
  2769. // compound packet. Failing to
  2770. // report buffer info is not a 
  2771. // critical error
  2772. HX_DELETE(pPktBufInfo);
  2773.     }
  2774.     // pack them up!
  2775.     theErr = m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
  2776.    (void**)&pSendBuf);
  2777.     if (HXR_OK != theErr)
  2778.     {
  2779. HX_ASSERT(!pSendBuf);
  2780. goto bail;
  2781.     }
  2782.     packer.Set(pPktRR);
  2783.     packer.Set(pPktSDES);
  2784.     if (pPktBufInfo)
  2785.     {
  2786. packer.Set(pPktBufInfo);
  2787.     }
  2788.     theErr = packer.Pack(pSendBuf);
  2789.     
  2790.     if (HXR_OK != theErr)
  2791.     {
  2792. HX_ASSERT(FALSE && "failed to create SR/SDES RTCP pkt");
  2793. goto bail;
  2794.     }
  2795. //    theErr = m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuf);
  2796.     m_pReportHandler->UpdateAvgRTCPSize(pSendBuf->GetSize());
  2797.     m_bSendBye = TRUE;
  2798. bail:
  2799.     HX_DELETE(pPktRR);
  2800.     HX_DELETE(pPktSDES);
  2801.     HX_DELETE(pPktBufInfo);
  2802. //    HX_RELEASE(pSendBuf);
  2803.     return theErr;
  2804. }
  2805. RTCPBaseTransport::ReportCallback::ReportCallback(RTCPBaseTransport* pTransport):
  2806.     m_pTransport(pTransport),
  2807.     m_lReportRefCount(0)
  2808. {
  2809.     if(m_pTransport)
  2810.     {
  2811. m_pTransport->AddRef();
  2812.     }
  2813. }
  2814. RTCPBaseTransport::ReportCallback::~ReportCallback()
  2815. {
  2816.     HX_RELEASE(m_pTransport);
  2817. }
  2818. STDMETHODIMP
  2819. RTCPBaseTransport::ReportCallback::QueryInterface(REFIID riid, void** ppvObj)
  2820. {
  2821.     if (IsEqualIID(riid, IID_IUnknown))
  2822.     {
  2823.         AddRef();
  2824.         *ppvObj = this;
  2825.         return HXR_OK;
  2826.     }
  2827.     else if (IsEqualIID(riid, IID_IHXCallback))
  2828.     {
  2829.         AddRef();
  2830.         *ppvObj = (IHXCallback*)this;
  2831.         return HXR_OK;
  2832.     }
  2833.     *ppvObj = NULL;
  2834.     return HXR_NOINTERFACE;
  2835. }
  2836. STDMETHODIMP_(UINT32)
  2837. RTCPBaseTransport::ReportCallback::AddRef()
  2838. {
  2839.     return InterlockedIncrement(&m_lReportRefCount);
  2840. }
  2841. STDMETHODIMP_(UINT32)
  2842. RTCPBaseTransport::ReportCallback::Release()
  2843. {
  2844.     if(InterlockedDecrement(&m_lReportRefCount) > 0)
  2845.     {
  2846. return m_lReportRefCount;
  2847.     }
  2848.     delete this;
  2849.     return 0;
  2850. }
  2851. STDMETHODIMP
  2852. RTCPBaseTransport::ReportCallback::Func()
  2853. {
  2854.     HX_ASSERT(!m_pTransport->m_bSendReport);
  2855.     HX_ASSERT(m_pTransport->m_bCallbackPending);
  2856.     m_pTransport->m_bCallbackPending = FALSE;
  2857.     if (m_pTransport->m_bSendRTCP)
  2858.     {
  2859. m_pTransport->m_bSendReport = TRUE;
  2860.     }
  2861.     return HXR_OK;
  2862. }
  2863. /*
  2864.  *  RTCP UDP
  2865.  */
  2866. RTCPUDPTransport::RTCPUDPTransport(BOOL bIsSource)
  2867.     : RTCPBaseTransport(bIsSource)
  2868.     , m_pUDPSocket(NULL)
  2869.     , m_foreignAddr(0)
  2870.     , m_foreignPort(0)
  2871.     , m_ulCurrentMulticastAddress(0)
  2872.     , m_ulCurrentMulticastPort(0)
  2873.     , m_pMCastUDPSocket(NULL)
  2874. {
  2875. }
  2876. RTCPUDPTransport::~RTCPUDPTransport()
  2877. {
  2878.     Done();
  2879. }
  2880. void
  2881. RTCPUDPTransport::Done()
  2882. {    
  2883.     if (m_bSendBye)
  2884.     {
  2885. sendBye();
  2886.     }
  2887.     m_keepAlive.reset();
  2888.     if (m_pMCastUDPSocket)
  2889.     {
  2890.         m_pMCastUDPSocket->LeaveMulticastGroup(m_ulCurrentMulticastAddress, HXR_INADDR_ANY);
  2891.     }
  2892.     HX_RELEASE(m_pMCastUDPSocket);
  2893.     HX_RELEASE(m_pUDPSocket);
  2894.     HX_RELEASE(m_pDataTransport);
  2895.     RTCPBaseTransport::Done();
  2896. }
  2897. RTSPTransportTypeEnum
  2898. RTCPUDPTransport::tag()
  2899. {
  2900.     return RTSP_TR_RTCP;
  2901. }
  2902. HX_RESULT
  2903. RTCPUDPTransport::init(IUnknown* pContext,
  2904.     IHXUDPSocket* pSocket,
  2905.     RTPUDPTransport* pDataTransport,
  2906.     IHXRTSPTransportResponse* pResp,
  2907.     UINT16 streamNumber)     
  2908. {
  2909.     m_pUDPSocket = pSocket;
  2910.     m_pUDPSocket->AddRef();
  2911.     m_pDataTransport = pDataTransport;
  2912.     m_pDataTransport->AddRef();
  2913.     m_pResp = pResp;
  2914.     pResp->AddRef();
  2915.     m_streamNumber = streamNumber;
  2916.     /* Set DiffServ Code Point */
  2917.     IHXSetSocketOption* pOpt = NULL;
  2918.     if (SUCCEEDED(m_pUDPSocket->QueryInterface(IID_IHXSetSocketOption, (void**)&pOpt)))
  2919.     {
  2920. IHXQoSDiffServConfigurator* pCfg = NULL;
  2921. if (SUCCEEDED(pContext->QueryInterface(IID_IHXQoSDiffServConfigurator, (void**)&pCfg)))
  2922. {
  2923.     pCfg->ConfigureSocket(pOpt, HX_QOS_DIFFSERV_CLASS_CONTROL);
  2924.     pCfg->Release();
  2925.     pCfg = NULL;
  2926. }
  2927. pOpt->Release();
  2928. pOpt = NULL;
  2929.     }
  2930.     
  2931.     HX_RESULT hresult = Init(pContext);
  2932.     if(HXR_OK != hresult)
  2933.     {
  2934. return hresult;
  2935.     }
  2936.     RTCPBaseTransport::init();
  2937.     
  2938.     return HXR_OK;
  2939. }
  2940. void
  2941. RTCPUDPTransport::setForeignAddress(UINT32 foreignAddr, UINT16 foreignPort)
  2942. {
  2943.     m_foreignAddr = foreignAddr;
  2944.     m_foreignPort = foreignPort;
  2945.     UINT32 natTimeout = GetNATTimeout(m_pContext);
  2946.     if (!m_bIsSource && natTimeout)
  2947.     {
  2948. // Initialize keepalive object
  2949. m_keepAlive.Init(m_pScheduler, natTimeout, new KeepAliveCB(this));
  2950.     
  2951. // Do initial "poke" through the NAT
  2952. onNATKeepAlive();
  2953.     }
  2954. }
  2955. HX_RESULT RTCPUDPTransport::handlePacket(IHXBuffer* pBuffer)
  2956. {
  2957.     m_keepAlive.OnActivity();
  2958.     return RTCPBaseTransport::handlePacket(pBuffer);
  2959. }
  2960. void 
  2961. RTCPUDPTransport::JoinMulticast(UINT32 ulAddress, UINT32 ulPort, IHXUDPSocket* pUDP)
  2962. {
  2963.     if (m_ulCurrentMulticastAddress)
  2964.     {
  2965. m_pMCastUDPSocket->LeaveMulticastGroup(m_ulCurrentMulticastAddress, HXR_INADDR_ANY);
  2966.     }
  2967.     else
  2968.     {
  2969. m_pMCastUDPSocket = pUDP;
  2970.         m_pMCastUDPSocket->AddRef();
  2971.     }
  2972.     m_pMCastUDPSocket->JoinMulticastGroup(ulAddress, HXR_INADDR_ANY);
  2973.     m_bMulticast = TRUE;
  2974.     m_ulCurrentMulticastAddress = ulAddress;
  2975.     m_ulCurrentMulticastPort = ulPort;
  2976.     if (m_pStreamHandler)
  2977.     {
  2978. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  2979. ASSERT(pStreamData);
  2980. while(pStreamData)
  2981. {
  2982.     pStreamData->m_pTransportBuffer->SetMulticast();
  2983.     pStreamData = m_pStreamHandler->nextStreamData();
  2984. }
  2985.     }
  2986.     return;
  2987. }
  2988. HX_RESULT RTCPUDPTransport::onNATKeepAlive()
  2989. {
  2990.     DPRINTF(D_INFO, ("RTCP: onNATKeepAlive()n"));
  2991.     if (m_bSendRTCP)
  2992.     {
  2993. // Send an early receiver report to keep
  2994. // the NAT port open
  2995. sendReceiverReport();
  2996.     }
  2997.     return HXR_OK;
  2998. }
  2999. HX_RESULT
  3000. RTCPUDPTransport::streamDone(UINT16 streamNumber)
  3001. {
  3002.     HX_ASSERT(streamNumber == m_streamNumber);
  3003.     HX_ASSERT(streamNumber == m_pDataTransport->m_streamNumber);
  3004.     // this will be called from RTPUDPTransport::streamDone();
  3005.     if (m_bSendBye)
  3006.     {
  3007. sendBye();
  3008.     }
  3009.     return HXR_OK;
  3010. }
  3011. /*
  3012.  *  We don't really konw what this RTCP pkt is...Simply reflect.
  3013.  */
  3014. HX_RESULT
  3015. RTCPUDPTransport::reflectRTCP(IHXBuffer* pSendBuf)
  3016. {
  3017.     HX_ASSERT(pSendBuf);
  3018.     return m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuf);    
  3019. }
  3020. HX_RESULT
  3021. RTCPUDPTransport::sendSenderReport()
  3022. {
  3023.     HX_ASSERT(m_bIsSource);
  3024.     HX_RESULT theErr;
  3025.     IHXBuffer* pSendBuf = NULL;
  3026.     theErr = makeSenderReport(pSendBuf);
  3027.     if (HXR_OK == theErr)
  3028.     {
  3029. HX_ASSERT(pSendBuf);
  3030. theErr = m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuf);
  3031.     }
  3032.     HX_RELEASE(pSendBuf);
  3033.     return theErr;
  3034. }
  3035. HX_RESULT
  3036. RTCPUDPTransport::sendReceiverReport()
  3037. {
  3038.     HX_ASSERT(!m_bIsSource);
  3039.     HX_RESULT theErr;
  3040.     IHXBuffer* pSendBuf = NULL;
  3041.     theErr = makeReceiverReport(pSendBuf);
  3042.     if (HXR_OK == theErr)
  3043.     {
  3044. HX_ASSERT(pSendBuf);
  3045. theErr = m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuf);
  3046.     }
  3047.     HX_RELEASE(pSendBuf);
  3048.     return theErr;
  3049. }
  3050. HX_RESULT
  3051. RTCPUDPTransport::sendBye()
  3052. {
  3053.     HX_RESULT theErr;
  3054.     IHXBuffer* pSendBuf = NULL;
  3055.     theErr = makeBye(pSendBuf);
  3056.     if (HXR_OK == theErr)
  3057.     {
  3058. HX_ASSERT(pSendBuf);
  3059.      if (m_bIsSource)
  3060.      {
  3061.     // we don't want this to get lost since a client will request for 
  3062.     // TEARDOWN upon a reception of this report.
  3063.     for (UINT32 i = 0; i < 5 && HXR_OK == theErr; i++)
  3064.     {
  3065.      theErr = m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuf);
  3066.     }     
  3067.      }
  3068.      else
  3069.      {
  3070.     theErr = m_pUDPSocket->WriteTo(m_foreignAddr, m_foreignPort, pSendBuf);
  3071.      }
  3072.     }
  3073.     HX_RELEASE(pSendBuf);
  3074.     return theErr;
  3075. }
  3076. RTCPUDPTransport::KeepAliveCB::KeepAliveCB(RTCPUDPTransport* pTransport):
  3077.     m_pTransport(pTransport),
  3078.     m_lRefCount(0)
  3079. {
  3080.     if(m_pTransport)
  3081.     {
  3082. m_pTransport->AddRef();
  3083.     }
  3084. }
  3085. RTCPUDPTransport::KeepAliveCB::~KeepAliveCB()
  3086. {
  3087.     HX_RELEASE(m_pTransport);
  3088. }
  3089. STDMETHODIMP
  3090. RTCPUDPTransport::KeepAliveCB::QueryInterface(REFIID riid, void** ppvObj)
  3091. {
  3092.     if (IsEqualIID(riid, IID_IUnknown))
  3093.     {
  3094.         AddRef();
  3095.         *ppvObj = this;
  3096.         return HXR_OK;
  3097.     }
  3098.     else if (IsEqualIID(riid, IID_IHXCallback))
  3099.     {
  3100.         AddRef();
  3101.         *ppvObj = (IHXCallback*)this;
  3102.         return HXR_OK;
  3103.     }
  3104.     *ppvObj = NULL;
  3105.     return HXR_NOINTERFACE;
  3106. }
  3107. STDMETHODIMP_(UINT32)
  3108. RTCPUDPTransport::KeepAliveCB::AddRef()
  3109. {
  3110.     return InterlockedIncrement(&m_lRefCount);
  3111. }
  3112. STDMETHODIMP_(UINT32)
  3113. RTCPUDPTransport::KeepAliveCB::Release()
  3114. {
  3115.     if(InterlockedDecrement(&m_lRefCount) > 0)
  3116.     {
  3117. return m_lRefCount;
  3118.     }
  3119.     delete this;
  3120.     return 0;
  3121. }
  3122. STDMETHODIMP
  3123. RTCPUDPTransport::KeepAliveCB::Func()
  3124. {
  3125.     if (m_pTransport)
  3126.     {
  3127. m_pTransport->onNATKeepAlive();
  3128.     }
  3129.     return HXR_OK;
  3130. }
  3131. /*
  3132.  *  RTCP TCP
  3133.  */
  3134. RTCPTCPTransport::RTCPTCPTransport(BOOL bIsSource)
  3135.     : RTCPBaseTransport(bIsSource)
  3136.     , m_pTCPSocket(NULL)
  3137.     , m_tcpInterleave((INT8)0xFF)
  3138. {
  3139. }
  3140. RTCPTCPTransport::~RTCPTCPTransport()
  3141. {
  3142.     Done();
  3143. }
  3144. void
  3145. RTCPTCPTransport::Done()
  3146. {    
  3147.     if (m_bSendBye)
  3148.     {
  3149. sendBye();
  3150.     }
  3151.     HX_RELEASE(m_pTCPSocket);
  3152.     HX_RELEASE(m_pDataTransport);
  3153.     RTCPBaseTransport::Done();
  3154. }
  3155. RTSPTransportTypeEnum
  3156. RTCPTCPTransport::tag()
  3157. {
  3158.     return RTSP_TR_RTCP;
  3159. }
  3160. HX_RESULT
  3161. RTCPTCPTransport::init(IUnknown* pContext,
  3162.     IHXTCPSocket* pSocket,
  3163.     RTPTCPTransport* pDataTransport,
  3164.     IHXRTSPTransportResponse* pResp,
  3165.     UINT16 streamNumber)     
  3166. {
  3167.     m_pTCPSocket = pSocket;
  3168.     m_pTCPSocket->AddRef();
  3169.     m_pDataTransport = pDataTransport;
  3170.     m_pDataTransport->AddRef();
  3171.     
  3172.     m_pResp = pResp;
  3173.     m_pResp->AddRef();
  3174.     m_streamNumber = streamNumber;
  3175.     /* Set DiffServ Code Point */
  3176.     IHXSetSocketOption* pOpt = NULL;
  3177.     if (SUCCEEDED(m_pTCPSocket->QueryInterface(IID_IHXSetSocketOption, (void**)&pOpt)))
  3178.     {
  3179. IHXQoSDiffServConfigurator* pCfg = NULL;
  3180. if (SUCCEEDED(pContext->QueryInterface(IID_IHXQoSDiffServConfigurator, (void**)&pCfg)))
  3181. {
  3182.     pCfg->ConfigureSocket(pOpt, HX_QOS_DIFFSERV_CLASS_CONTROL);
  3183.     pCfg->Release();
  3184.     pCfg = NULL;
  3185. }
  3186. pOpt->Release();
  3187. pOpt = NULL;
  3188.     }
  3189.     
  3190.     HX_RESULT hresult = Init(pContext);
  3191.     if(HXR_OK != hresult)
  3192.     {
  3193. return hresult;
  3194.     }
  3195.     RTCPBaseTransport::init();
  3196.     
  3197.     return HXR_OK;
  3198. }
  3199. HX_RESULT
  3200. RTCPTCPTransport::streamDone(UINT16 streamNumber)
  3201. {
  3202.     HX_ASSERT(streamNumber == m_streamNumber);
  3203.     HX_ASSERT(streamNumber == m_pDataTransport->m_streamNumber);
  3204.     // this will be called from RTPUDPTransport::streamDone();
  3205.     if (m_bSendBye)
  3206.     {
  3207. sendBye();
  3208.     }
  3209.     return HXR_OK;
  3210. }
  3211. HX_RESULT
  3212. RTCPTCPTransport::reflectRTCP(IHXBuffer* pSendBuf)
  3213. {
  3214.     HX_ASSERT(pSendBuf);
  3215.     HX_RESULT theErr = writePacket(pSendBuf);    
  3216.     if (theErr)
  3217.     {
  3218. m_pResp->OnProtocolError(HXR_NET_SOCKET_INVALID);
  3219.     }
  3220.     return theErr;
  3221. }
  3222. HX_RESULT
  3223. RTCPTCPTransport::sendSenderReport()
  3224. {
  3225.     HX_RESULT theErr;
  3226.     IHXBuffer* pSendBuf = NULL;
  3227.     theErr = makeSenderReport(pSendBuf);
  3228.     if (HXR_OK == theErr)
  3229.     {
  3230. HX_ASSERT(pSendBuf);
  3231. theErr = writePacket(pSendBuf);
  3232.      if(theErr)
  3233.      {
  3234.     m_pResp->OnProtocolError(HXR_NET_SOCKET_INVALID);
  3235.      }
  3236.     }
  3237.     HX_RELEASE(pSendBuf);
  3238.     return theErr;
  3239. }
  3240. HX_RESULT
  3241. RTCPTCPTransport::sendReceiverReport()
  3242. {
  3243.     HX_RESULT theErr;
  3244.     IHXBuffer* pSendBuf = NULL;
  3245.     theErr = makeReceiverReport(pSendBuf);
  3246.     if (HXR_OK == theErr)
  3247.     {
  3248. HX_ASSERT(pSendBuf);
  3249. theErr = writePacket(pSendBuf);
  3250.      if(theErr)
  3251.      {
  3252.     m_pResp->OnProtocolError(HXR_NET_SOCKET_INVALID);
  3253.      }
  3254.     }
  3255.     HX_RELEASE(pSendBuf);
  3256.     return theErr;
  3257. }
  3258. HX_RESULT
  3259. RTCPTCPTransport::sendBye()
  3260. {
  3261.     HX_RESULT theErr;
  3262.     IHXBuffer* pSendBuf = NULL;
  3263.     theErr = makeBye(pSendBuf);
  3264.     if (HXR_OK == theErr)
  3265.     {
  3266. HX_ASSERT(pSendBuf);
  3267. theErr = writePacket(pSendBuf);
  3268. /*
  3269.  * this write will fail if a client initiated a teardown before the end 
  3270.  * of a clip because by the time we send BYE, a sock is gone!  So, don't
  3271.  * worry about return code here.
  3272.  */
  3273.     }
  3274.     HX_RELEASE(pSendBuf);
  3275.     return theErr;
  3276. }
  3277. HX_RESULT
  3278. RTCPTCPTransport::writePacket(IHXBuffer* pBuf)
  3279. {
  3280.     if (!m_pTCPSocket)
  3281.         return HXR_FAIL;
  3282.     // need to put $00[datalen] in front of packet data    
  3283.     HX_ASSERT(pBuf);
  3284.     UINT32 dataLen = pBuf->GetSize();
  3285.     if(dataLen > 0xffff)
  3286.     {
  3287. return HXR_FAIL;
  3288.     }
  3289.     //XXXTDM: always true, m_tcpInteleave is signed (why?)
  3290.     //HX_ASSERT(0xFF != m_tcpInterleave);
  3291.     IHXBuffer* pHeader = NULL;
  3292.     m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
  3293.                                           (void**)&pHeader);
  3294.     BYTE* pHeaderData;
  3295.     if(!pHeader)
  3296.     {
  3297.         return HXR_OUTOFMEMORY;
  3298.     }
  3299.     pHeader->SetSize(4);
  3300.     pHeaderData = pHeader->GetBuffer();
  3301.     pHeaderData[0] = '$';
  3302.     pHeaderData[1] = m_tcpInterleave;
  3303.     putshort(&pHeaderData[2], (UINT16)dataLen);
  3304.     HX_RESULT rc;
  3305.     rc = m_pTCPSocket->Write(pHeader);
  3306.     if (SUCCEEDED(rc))
  3307.     {
  3308.         rc = m_pTCPSocket->Write(pBuf);
  3309.     }
  3310.     pHeader->Release();
  3311.     return rc;
  3312. }