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

Symbian

Development Platform:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: rtsptran.cpp,v 1.22.8.1 2004/07/09 02:04:41 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxtypes.h"
  50. #include "hxassert.h"
  51. #include "debug.h"
  52. #include "hxcom.h"
  53. #include "hxmarsh.h"
  54. #include "hxstrutl.h"
  55. #include "netbyte.h"
  56. #include "hxengin.h"
  57. #include "ihxpckts.h"
  58. #include "hxcomm.h"
  59. #include "hxmon.h"
  60. #include "netbyte.h"
  61. #include "hxstring.h"
  62. #include "chxpckts.h"
  63. #include "hxslist.h"
  64. #include "hxmap.h"
  65. #include "hxdeque.h"
  66. #include "hxbitset.h"
  67. #include "timebuff.h"
  68. #include "timeval.h"
  69. #include "tconverter.h"
  70. #include "rtptypes.h"
  71. #include "rtspmsg.h"
  72. #include "hxcorgui.h"
  73. #include "ntptime.h"
  74. #include "rtspif.h"
  75. #include "rtsptran.h"
  76. //#include "rtpwrap.h" // Wrappers for PMC generated base classes
  77. #include "basepkt.h"
  78. #include "hxtbuf.h"
  79. #include "transbuf.h"
  80. #include "hxtick.h"
  81. #include "random32.h" // random32()
  82. #include "pkthndlr.h" // in rtpmisc for RTCP routine
  83. #include "rtcputil.h" // takes care of RTCP in RTP mode
  84. #include "hxprefs.h" // IHXPreferences
  85. #include "hxmime.h"
  86. #include "hxcore.h"
  87. #include "hxheap.h"
  88. #ifdef PAULM_IHXTCPSCAR
  89. #include "objdbg.h"
  90. #endif
  91. #ifdef PAULM_TNGTCPTRANSTIMING
  92. #include "classtimer.h"
  93. ClassTimer g_TNGTCPTransTimer("TNGTCPTransport", 0, 3600);
  94. #endif
  95. #ifdef _DEBUG
  96. #undef HX_THIS_FILE
  97. static const char HX_THIS_FILE[] = __FILE__;
  98. #endif
  99. #define STREAM_END_DELAY_BASE_TOLERANCE 3000
  100. static const UINT32 TRANSPORT_BUF_GROWTH_RATE  = 1000;
  101. void
  102. dump(const char* pFile, const char* pc)
  103. {
  104.     FILE* fp = fopen(pFile, "a");
  105.     if(!fp)
  106.     {
  107.     return;
  108.     }
  109.     fprintf(fp, "%s", pc);
  110.     fclose(fp);    
  111. }
  112. RTSPStreamData::RTSPStreamData(BOOL needReliable):
  113.     m_seqNo(0),
  114.     m_streamNumber(0),
  115.     m_reliableSeqNo(0),
  116.     m_lastTimestamp(0),
  117.     m_pTransportBuffer(0),
  118.     m_pResendBuffer(0),
  119.     m_pStreamStats(0),
  120.     m_bNeedReliable(needReliable),
  121.     m_packetSent(FALSE),
  122.     m_bReceivedAllPackets(FALSE),
  123.     m_bNeedToACK(FALSE),
  124.     m_bFirstPacket(TRUE),
  125.     m_bUsesRTPPackets(FALSE),
  126.     m_pTSConverter(NULL),
  127.     m_pTSOrderHack(NULL),
  128.     m_eMediaType(RTSPMEDIA_TYPE_UNKNOWN)
  129. {
  130.     ;
  131. }
  132. RTSPStreamData::~RTSPStreamData()
  133. {
  134.     if (m_pTransportBuffer)
  135.     {
  136. delete m_pTransportBuffer;
  137.     }
  138.     if (m_pResendBuffer)
  139.     {
  140. delete m_pResendBuffer;
  141.     }
  142.     HX_DELETE(m_pTSConverter);
  143.     HX_DELETE(m_pTSOrderHack);
  144. }
  145. RTSPStreamHandler::RTSPStreamHandler(RTSPTransport* pOwner)
  146.     : m_pOwner(pOwner)
  147.     , m_lRefCount(0)
  148. {
  149.     m_pStreamDataMap = new CHXMapLongToObj;
  150. }
  151. RTSPStreamHandler::~RTSPStreamHandler()
  152. {
  153.     CHXMapLongToObj::Iterator i;
  154.     RTSPStreamData* pStreamData;
  155.     for(i=m_pStreamDataMap->Begin();i!=m_pStreamDataMap->End();++i)
  156.     {
  157. pStreamData = (RTSPStreamData*)(*i);
  158. delete pStreamData;
  159.     }
  160.     delete m_pStreamDataMap;
  161. }
  162. HX_RESULT
  163. RTSPStreamHandler::initStreamData(
  164.     UINT16 streamNumber, BOOL needReliable, BOOL bIsSource, INT16 rtpPayloadType,
  165.     BOOL bRecordFlag, UINT32 wrapSequenceNumber, UINT32 ulBufferDepth,
  166.     BOOL bHasOutOfOrderTS, CHXTimestampConverter* pTSConverter,
  167.     RTSPMediaType eMediaType)
  168. {
  169.     RTSPStreamData* pStreamData;
  170.     if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
  171.     {
  172. pStreamData = new RTSPStreamData(needReliable);
  173. pStreamData->m_streamNumber = streamNumber;
  174.         pStreamData->m_pTSConverter = pTSConverter;
  175. pStreamData->m_eMediaType = eMediaType;
  176. pStreamData->m_lastSeqNo = 0;
  177. (*m_pStreamDataMap)[streamNumber] = pStreamData;
  178. if (!bIsSource)
  179. {
  180.     UINT32 ulSetMaximumBufferDepth;
  181.     UINT32 ulSetBufferDepth;
  182.     if (bRecordFlag && ulBufferDepth != TRANSPORT_BUF_DURATION_UNDEF)
  183.     {
  184.      ulSetMaximumBufferDepth = ulBufferDepth;
  185.      ulSetBufferDepth = ulBufferDepth;
  186.     }
  187.     else if (bRecordFlag)
  188.     {
  189.      ulSetMaximumBufferDepth = MAX_TRANSPORT_BUF_DURATION;
  190.      ulSetBufferDepth = MAX_TRANSPORT_BUF_DURATION;
  191.     }
  192.     else
  193.     {
  194.      ulSetMaximumBufferDepth = MAX_TRANSPORT_BUF_DURATION;
  195.      ulSetBufferDepth = TRANSPORT_BUF_DURATION;
  196.     }
  197.     RTSPTransportBuffer* pTransportBuffer = 
  198. new RTSPTransportBuffer(m_pOwner,
  199.                                 streamNumber,
  200.                                 ulSetBufferDepth,
  201.                                 ulSetMaximumBufferDepth,
  202.                                 TRANSPORT_BUF_GROWTH_RATE,
  203.                                 wrapSequenceNumber);
  204.     pStreamData->m_pTransportBuffer = pTransportBuffer;
  205.     pStreamData->m_pStreamStats = NULL;
  206.     pStreamData->m_bUsesRTPPackets = bHasOutOfOrderTS;
  207. }
  208. return HXR_OK;
  209.     }
  210.     return HXR_FAIL;
  211. }
  212. RTSPStreamData*
  213. RTSPStreamHandler::getStreamData(UINT16 streamNumber)
  214. {
  215.     RTSPStreamData* pStreamData = 0;
  216.     if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
  217.     {
  218. return 0;
  219.     }
  220.     return pStreamData;
  221. }
  222. RTSPStreamData*
  223. RTSPStreamHandler::firstStreamData()
  224. {
  225.     streamIterator = m_pStreamDataMap->Begin();
  226.     if(streamIterator == m_pStreamDataMap->End())
  227.     {
  228. return 0;
  229.     }
  230.     return (RTSPStreamData*)(*streamIterator);
  231. }
  232. RTSPStreamData*
  233. RTSPStreamHandler::nextStreamData()
  234. {
  235.     ++streamIterator;
  236.     if(streamIterator == m_pStreamDataMap->End())
  237.     {
  238. return 0;
  239.     }
  240.     return (RTSPStreamData*)(*streamIterator);
  241. }
  242. BOOL
  243. RTSPStreamHandler::endStreamData()
  244. {
  245.     return (streamIterator == m_pStreamDataMap->End());
  246. }
  247. HX_RESULT
  248. RTSPStreamHandler::createResendBuffer(UINT16 streamNumber,
  249.       UINT32 wrapSequenceNumber)
  250. {
  251.     RTSPStreamData* pStreamData;
  252.     if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
  253.     {
  254. return HXR_FAILED;
  255.     }
  256.     RTSPResendBuffer* pResendBuffer;
  257.     pResendBuffer = new RTSPResendBuffer(RESEND_BUF_DURATION,
  258.                                          MAX_RESEND_BUF_DURATION,
  259.                                          RESEND_BUF_GROWTH_RATE,
  260.                                          wrapSequenceNumber);
  261.     pStreamData->m_pResendBuffer = pResendBuffer;
  262.     return HXR_OK;
  263. }
  264. RTSPResendBuffer*
  265. RTSPStreamHandler::getResendBuffer(UINT16 streamNumber)
  266. {
  267.     RTSPStreamData* pStreamData = 0;
  268.     if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
  269.     {
  270. return 0;
  271.     }
  272.     return pStreamData->m_pResendBuffer;
  273. }
  274. /*
  275.  * RTSPTransport methods
  276.  */
  277. RTSPTransport::RTSPTransport(BOOL bIsSource):
  278.     m_pContext(NULL),
  279.     m_pCommonClassFactory(0),
  280.     m_pScheduler(0),
  281.     m_pResp(0),
  282.     m_pStreamHandler(0),
  283.     m_pRegistry(0),
  284.     m_pInternalReset(0),
  285.     m_pSrcBufferStats(0),
  286.     m_bIsSource(bIsSource),
  287.     m_bIsInitialized(FALSE),
  288.     m_bIsUpdated(FALSE),
  289.     m_ulPacketsSent(0),
  290.     m_lBytesSent(0),
  291.     m_bIsReceivedData(FALSE),
  292.     m_bSourceDone(FALSE),
  293.     m_bHackedRecordFlag(FALSE),
  294.     m_wrapSequenceNumber(0),
  295.     m_bMulticast(FALSE),
  296.     m_pPlayerState(NULL),
  297.     m_pPacketFilter(NULL),
  298.     m_pClientPacketList(NULL),
  299.     m_bPrefetch(FALSE),
  300.     m_bFastStart(FALSE),
  301.     m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
  302.     m_ulPlayRangeTo(RTSP_PLAY_RANGE_BLANK),
  303.     m_bPlayRequestSent(FALSE),
  304.     m_packets_since_last_drop(0),
  305.     m_ulTotalSuccessfulResends(0),
  306.     m_ulTotalFailedResends(0),
  307.     m_ulSendingTime(0),
  308.     m_drop_packets(FALSE),
  309.     m_bSkipTimeAdjustment(FALSE)
  310. #ifdef RDT_MESSAGE_DEBUG
  311.     ,m_bRDTMessageDebug(FALSE)
  312. #endif    
  313. {
  314.     m_ulStartTime = HX_GET_TICKCOUNT();
  315. }
  316. RTSPTransport::~RTSPTransport()
  317. {
  318.     HX_RELEASE(m_pCommonClassFactory);
  319.     HX_RELEASE(m_pScheduler);
  320.     HX_RELEASE(m_pResp);
  321.     HX_RELEASE(m_pRegistry);
  322.     if (m_pStreamHandler)
  323.     {
  324.         m_pStreamHandler->Release();
  325.         m_pStreamHandler = NULL;
  326.     }
  327.     HX_RELEASE(m_pInternalReset);
  328.     HX_RELEASE(m_pSrcBufferStats);
  329.     HX_RELEASE(m_pPlayerState);
  330.     HX_RELEASE(m_pPacketFilter);
  331.     HX_RELEASE(m_pContext);
  332.     HX_DELETE(m_pClientPacketList);
  333. }
  334. void
  335. RTSPTransport::addStreamInfo(RTSPStreamInfo* pStreamInfo, UINT32 ulBufferDepth)
  336. {
  337.     if(pStreamInfo)
  338.     {
  339. if(!m_pStreamHandler)
  340. {
  341.     m_pStreamHandler = new RTSPStreamHandler(this);
  342.     m_pStreamHandler->AddRef();
  343. }
  344. CHXTimestampConverter*  pTSConverter = NULL;
  345. if (pStreamInfo->m_HXFactor && pStreamInfo->m_RTPFactor)
  346. {
  347.     pTSConverter = new CHXTimestampConverter(CHXTimestampConverter::FACTORS,
  348.      pStreamInfo->m_HXFactor,
  349.      pStreamInfo->m_RTPFactor);
  350.  }
  351.  else if (pStreamInfo->m_sampleRate)
  352.  {
  353.      
  354.      pTSConverter =  new CHXTimestampConverter(CHXTimestampConverter::SAMPLES,
  355.        pStreamInfo->m_sampleRate);
  356.  }
  357.  m_pStreamHandler->initStreamData(
  358.      pStreamInfo->m_streamNumber,
  359.      pStreamInfo->m_bNeedReliablePackets,
  360.      m_bIsSource,
  361.      pStreamInfo->m_rtpPayloadType,
  362.      m_bHackedRecordFlag,
  363.      m_wrapSequenceNumber,
  364.      ulBufferDepth,
  365.      pStreamInfo->m_bHasOutOfOrderTS,
  366.      pTSConverter,
  367.      pStreamInfo->m_eMediaType);
  368.         m_bSkipTimeAdjustment = pStreamInfo->m_bRealMedia;
  369. RTSPStreamData* pStreamData = NULL;
  370. pStreamData = m_pStreamHandler->getStreamData(pStreamInfo->m_streamNumber);
  371. if (pStreamData && pStreamData->m_pTransportBuffer && m_bPrefetch)
  372. {
  373.     pStreamData->m_pTransportBuffer->EnterPrefetch();
  374. }
  375.     }
  376. }
  377. void
  378. RTSPTransport::setFirstTimeStamp(UINT16 uStreamNumber, UINT32 ulTS, 
  379.                                  BOOL bIsRaw)
  380. {
  381.     RTSPStreamData* pStreamData = 
  382. m_pStreamHandler->getStreamData(uStreamNumber);
  383.     if (pStreamData)
  384.     {
  385. if (pStreamData->m_pTSConverter)
  386. {
  387.     pStreamData->m_pTSConverter->setHXAnchor(ulTS);
  388. }
  389.          
  390. HX_DELETE(pStreamData->m_pTSOrderHack);
  391.     }
  392.     if (!m_bIsSource)
  393.     {
  394. RTSPTransportBuffer* pTransportBuffer = pStreamData->m_pTransportBuffer;
  395. if (pTransportBuffer && pStreamData)
  396. {
  397.     if ((m_ulPlayRangeFrom != RTSP_PLAY_RANGE_BLANK) &&
  398. (m_ulPlayRangeTo != RTSP_PLAY_RANGE_BLANK))
  399.     {
  400. if ((pStreamData->m_eMediaType == RTSPMEDIA_TYPE_AUDIO) ||
  401.     (pStreamData->m_eMediaType == RTSPMEDIA_TYPE_VIDEO))
  402. {
  403.     // For audio & video media, we'll inform transport of
  404.     // the media duration to help determining stream termination
  405.     pStreamData->m_pTransportBuffer->InformTimestampRange(
  406. m_ulPlayRangeFrom,
  407. m_ulPlayRangeTo,
  408. STREAM_END_DELAY_BASE_TOLERANCE);
  409. }
  410.     }
  411. }
  412.     }
  413. }
  414. void 
  415. RTSPTransport::setPlayRange(UINT32 ulFrom, UINT32 ulTo)
  416. {
  417.     // this is the Range values in PLAY request in RMA time (ms) called on PLAY 
  418.     // request
  419.     m_ulPlayRangeFrom = ulFrom; 
  420.     m_ulPlayRangeTo = ulTo;
  421. }
  422. void
  423. RTSPTransport::setSessionID(const char* pSessionID)
  424. {
  425.     m_sessionID = pSessionID;
  426. }
  427. UINT16
  428. RTSPTransport::getSeqNum(UINT16 streamNumber)
  429. {
  430.     RTSPStreamData* pStreamData;
  431.     pStreamData = m_pStreamHandler->getStreamData(streamNumber);
  432.     if(pStreamData)
  433.     {
  434. return pStreamData->m_seqNo;
  435.     }
  436.     else
  437.     {
  438. return 0; //XXXBAB - 0xffff?
  439.     }
  440. }
  441. UINT32
  442. RTSPTransport::getTimestamp(UINT16 streamNumber)
  443. {
  444.     RTSPStreamData* pStreamData;
  445.     pStreamData = m_pStreamHandler->getStreamData(streamNumber);
  446.     if(pStreamData)
  447.     {
  448. // XXXGo - this is RTP time w/ offset (NOT RMA time) if RTPUDPTransprot...
  449. return pStreamData->m_lastTimestamp;
  450.     }
  451.     else
  452.     {
  453. return 0;
  454.     }
  455. }
  456. HX_RESULT
  457. RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
  458. {
  459.     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
  460.     RTSPStreamData* pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
  461.     if ((!pTransportBuffer) || (!pStreamData))
  462.     {
  463. return HXR_FAIL;
  464.     }
  465.     ClientPacket* clientPacket;
  466.     HX_RESULT result = pTransportBuffer->GetPacket(clientPacket);
  467.     if (result != HXR_OK)
  468.     {
  469. return result;
  470.     }
  471.     pPacket = clientPacket->GetPacket();
  472.     if (!pPacket)
  473.     {
  474. /*
  475.  * This is a lost packet
  476.  */
  477. result = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket,
  478.                                                (void**)&pPacket);
  479. if (result != HXR_OK)
  480. {
  481.     return result;
  482. }
  483. UINT8 unASMFlags = 0;
  484. UINT32 ulTime = 0;
  485. if (clientPacket->IsDroppedPacket())
  486. {
  487.     // Preserve dropped flag as an ASM flag.
  488.     // This allows other code along the packet
  489.     // path to differentiate this packet from a 
  490.     // true lost packet.
  491.     unASMFlags |= HX_ASM_DROPPED_PKT;
  492.     // We have a valid timestamp for a dropped
  493.     // packet so lets put it in the IHXPacket
  494.     ulTime = clientPacket->GetTime();
  495. }
  496. pPacket->Set(0, ulTime, uStreamNumber, unASMFlags, 0);
  497. pPacket->SetAsLost();
  498.     }
  499.     else if (pStreamData->m_bUsesRTPPackets)
  500.     {
  501. if (!pStreamData->m_pTSOrderHack)
  502. {
  503.     pStreamData->m_pTSOrderHack = new RTSPStreamData::TSOrderHackInfo();
  504.     
  505.     if (pStreamData->m_pTSOrderHack)
  506.     {
  507. pStreamData->m_pTSOrderHack->m_ulLastSentTS = 
  508.     pPacket->GetTime();
  509. pStreamData->m_pTSOrderHack->m_ulLastRecvTS = 
  510.     pStreamData->m_pTSOrderHack->m_ulLastSentTS;
  511.     }
  512. }
  513. if (pStreamData->m_pTSOrderHack)
  514. {
  515.     IHXBuffer* pBuf=NULL;     
  516.     UINT32 ulHX;
  517.     UINT32 ulRTP;
  518.     UINT16 unStrmNo;
  519.     UINT8  uchASMFlag;
  520.     UINT16 unRuleNo;
  521.     // pkts've been sorted based on seq_no
  522.     IHXRTPPacket* pRTPPacket = NULL;
  523.     pPacket->QueryInterface(IID_IHXRTPPacket, (void**) &pRTPPacket);
  524.     if (pRTPPacket)
  525.     {
  526. // RTP transport generates RTP packets
  527. result = pRTPPacket->GetRTP(pBuf, ulHX, ulRTP, 
  528.     unStrmNo, uchASMFlag, unRuleNo);
  529.     }
  530.     else
  531.     {
  532. // RDT transport generates RMA packets
  533. result = pPacket->Get(pBuf, ulHX,
  534.       unStrmNo, uchASMFlag, unRuleNo);
  535. if (pStreamData->m_pTSConverter)
  536. {
  537.     ulRTP = pStreamData->m_pTSConverter->hxa2rtp(ulHX);
  538. }
  539. else
  540. {
  541.     ulRTP = ulHX;
  542. }
  543.     }
  544.     HX_ASSERT(result == HXR_OK);
  545.     if (result == HXR_OK)
  546.     {
  547. if (((LONG32) (ulHX - pStreamData->m_pTSOrderHack->m_ulLastSentTS)) > 0)
  548. {
  549.     pStreamData->m_pTSOrderHack->m_ulLastSentTS = ulHX;
  550.     pStreamData->m_pTSOrderHack->m_ulLastRecvTS = ulHX;
  551. }
  552. else if (ulHX == pStreamData->m_pTSOrderHack->m_ulLastRecvTS)
  553. {
  554.     ulHX = pStreamData->m_pTSOrderHack->m_ulLastSentTS;          
  555. }
  556. else
  557. {
  558.     pStreamData->m_pTSOrderHack->m_ulLastRecvTS = ulHX;
  559.     ulHX = (++pStreamData->m_pTSOrderHack->m_ulLastSentTS);
  560. }
  561. HX_RELEASE(pRTPPacket);
  562. HX_RELEASE(pPacket);
  563. pRTPPacket = new CHXRTPPacket;
  564. pRTPPacket->AddRef();
  565. result = pRTPPacket->SetRTP(pBuf,
  566.     ulHX,
  567.     ulRTP,
  568.     unStrmNo,
  569.     uchASMFlag,
  570.     unRuleNo);
  571. HX_ASSERT(result == HXR_OK);
  572. pRTPPacket->QueryInterface(IID_IHXPacket, (void**) &pPacket);
  573. HX_ASSERT(pPacket);
  574.     }
  575.     HX_RELEASE(pBuf);
  576.     HX_RELEASE(pRTPPacket);
  577. }
  578.     }
  579.     /*
  580.      * No longer need the ClientPacket wrapper
  581.      */
  582.     HX_RELEASE(clientPacket);    
  583.     return HXR_OK;
  584. }
  585. HX_RESULT
  586. RTSPTransport::startPackets(UINT16 uStreamNumber)
  587. {
  588.     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
  589.     if (!pTransportBuffer)
  590.     {
  591. return HXR_FAIL;
  592.     }
  593.     return pTransportBuffer->StartPackets();
  594. }
  595. HX_RESULT
  596. RTSPTransport::stopPackets(UINT16 uStreamNumber)
  597. {
  598.     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
  599.     if (!pTransportBuffer)
  600.     {
  601. return HXR_FAIL;
  602.     }
  603.     return pTransportBuffer->StopPackets();
  604. }
  605. void
  606. RTSPTransport::SetFilterResponse(RawPacketFilter* pResp)
  607. {
  608.     HX_RELEASE(m_pPacketFilter);
  609.     m_pPacketFilter = pResp;
  610.     if (m_pPacketFilter)
  611.     {
  612. m_pPacketFilter->AddRef();
  613.     }
  614. }
  615. void
  616. RTSPTransport::FilterPacket(IHXPacket* pPacket)
  617. {
  618.     UINT16 uStreamNumber;
  619.     ClientPacket* clientPacket = 0;
  620.     clientPacket = (ClientPacket*)m_pClientPacketList->RemoveTail();
  621.     clientPacket->SetPacket(pPacket);
  622.     
  623.     uStreamNumber = clientPacket->GetStreamNumber();
  624.     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
  625.     pTransportBuffer->Add(clientPacket);
  626. }
  627. void RTSPTransport::GetContext(IUnknown*& pContext)   
  628. {   
  629. pContext = m_pContext;   
  630. if (pContext)   
  631. {   
  632. pContext->AddRef();   
  633. }   
  634. void 
  635. RTSPTransport::LeavePrefetch(void)
  636. {
  637.     RTSPStreamData* pStreamData = NULL; 
  638.     
  639.     m_bPrefetch = FALSE;
  640.     HX_ASSERT(m_pStreamHandler);
  641.     pStreamData = m_pStreamHandler->firstStreamData();
  642.     while(pStreamData)    
  643.     {
  644. if (pStreamData->m_pTransportBuffer)
  645. {
  646.     pStreamData->m_pTransportBuffer->LeavePrefetch();
  647. }
  648. pStreamData = m_pStreamHandler->nextStreamData();
  649.     }
  650.     return;
  651. }
  652. void 
  653. RTSPTransport::EnterFastStart(void)
  654. {
  655.     RTSPStreamData* pStreamData = NULL; 
  656.     
  657.     m_bFastStart = TRUE;
  658.     HX_ASSERT(m_pStreamHandler);
  659.     pStreamData = m_pStreamHandler->firstStreamData();
  660.     while(pStreamData)    
  661.     {
  662. if (pStreamData->m_pTransportBuffer)
  663. {
  664.     pStreamData->m_pTransportBuffer->EnterFastStart();
  665. }
  666. pStreamData = m_pStreamHandler->nextStreamData();
  667.     }
  668.     return;
  669. }
  670. void 
  671. RTSPTransport::LeaveFastStart(void)
  672. {
  673.     RTSPStreamData* pStreamData = NULL; 
  674.     
  675.     m_bFastStart = FALSE;
  676.     HX_ASSERT(m_pStreamHandler);
  677.     pStreamData = m_pStreamHandler->firstStreamData();
  678.     while(pStreamData)    
  679.     {
  680. if (pStreamData->m_pTransportBuffer)
  681. {
  682.     pStreamData->m_pTransportBuffer->LeaveFastStart();
  683. }
  684. pStreamData = m_pStreamHandler->nextStreamData();
  685.     }
  686.     return;
  687. }
  688. BOOL 
  689. RTSPTransport::isSparseStream(UINT16 uStreamNumber)
  690. {
  691.     BOOL bResult = FALSE;
  692.     const char* pMimeType = NULL;
  693.     IUnknown* pUnknown = NULL;
  694.     IHXStreamSource* pStreamSource = NULL;    
  695.     IHXStream* pStream = NULL;
  696.     if (m_pContext  &&
  697. HXR_OK == m_pContext->QueryInterface(IID_IHXStreamSource, (void**)&pStreamSource))
  698.     {
  699. if (HXR_OK == pStreamSource->GetStream(uStreamNumber, pUnknown))
  700. {
  701.     if (HXR_OK == pUnknown->QueryInterface(IID_IHXStream, (void**)&pStream))
  702.     {
  703. pMimeType = pStream->GetStreamType();
  704. // special handling for sparsed streams for multicast
  705. if (pMimeType &&
  706.     (strcasecmp(SYNCMM_MIME_TYPE, pMimeType) == 0 ||
  707.      strcasecmp(REALEVENT_MIME_TYPE, pMimeType) == 0 ||
  708.      strcasecmp("application/vnd.rn-realtext", pMimeType) == 0 ||
  709.      strcasecmp("application/x-pn-realtext", pMimeType) == 0))
  710. {
  711.     bResult = TRUE;
  712. }
  713.     }
  714.     HX_RELEASE(pStream);
  715. }
  716. HX_RELEASE(pUnknown);
  717.     }
  718.     HX_RELEASE(pStreamSource);
  719.     return bResult;
  720. }
  721. HX_RESULT
  722. RTSPTransport::storePacket(IHXPacket* pPacket,
  723.                            UINT16 uStreamNumber,
  724.                            UINT16 uSeqNo,
  725.                            UINT16 uReliableSeqNo,
  726.                            BOOL isReliable)
  727. {
  728.     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
  729.     if (!pTransportBuffer)
  730.     {
  731. return HXR_FAIL;
  732.     }
  733.     ClientPacket* clientPacket = 0;
  734.     
  735.     m_bIsReceivedData = TRUE;
  736.     if (pPacket->IsLost())
  737.     {
  738.         clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
  739.                         pPacket->GetTime(), 0, isReliable,
  740.                         0, pTransportBuffer->GetTime(), FALSE);
  741. clientPacket->AddRef();
  742. return pTransportBuffer->Add(clientPacket);
  743.     }
  744.     
  745.     IHXBuffer* pBuffer = pPacket->GetBuffer();
  746.     if (m_pPacketFilter)
  747.     {
  748. if (!m_pClientPacketList)
  749. {
  750.     m_pClientPacketList = new CHXSimpleList;
  751.     m_pPacketFilter->SetFilterResponse(this);
  752. }
  753. clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
  754. pPacket->GetTime(), pBuffer->GetSize(), isReliable,
  755. NULL, pTransportBuffer->GetTime(),
  756. FALSE);
  757. clientPacket->AddRef();
  758. pBuffer->Release();
  759. m_pClientPacketList->AddHead((void*)clientPacket);
  760. m_pPacketFilter->FilterPacket(pPacket);
  761. // just guessing on what this should be?????
  762.         return HXR_OK;
  763.     }
  764.     else
  765.     {
  766.        clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
  767. pPacket->GetTime(), pBuffer->GetSize(), isReliable,
  768. pPacket, pTransportBuffer->GetTime(), FALSE);
  769. clientPacket->AddRef();
  770. pBuffer->Release();
  771. return pTransportBuffer->Add(clientPacket);
  772.     }
  773. }
  774. HX_RESULT
  775. RTSPTransport::packetReady(HX_RESULT status, RTSPStreamData* pStreamData, IHXPacket* pPacket)
  776. {
  777.     HX_RESULT result = HXR_OK;
  778.     ASSERT(!m_bIsSource);
  779.     if (!pStreamData)
  780.     {
  781. return HXR_UNEXPECTED;
  782.     }
  783.     HX_ASSERT(pStreamData);
  784.     
  785.     if (pPacket)
  786.     {
  787. if (pStreamData->m_bUsesRTPPackets)
  788. {
  789.     IHXRTPPacket* pRTPPacket = NULL;
  790.     pPacket->QueryInterface(IID_IHXRTPPacket, (void**) &pRTPPacket);
  791.     if (pRTPPacket)
  792.     {
  793. // This already is RTP Packet - proceed
  794. pRTPPacket->Release();
  795.     }
  796.     else
  797.     {
  798. // Must Transfer to an RTP Packet
  799. result = m_pCommonClassFactory->CreateInstance(
  800. CLSID_IHXRTPPacket,
  801. (void**) &pRTPPacket);
  802. if (pRTPPacket)
  803. {
  804.     ULONG32 ulTime;
  805.     ULONG32 ulRTPTime;
  806.     UINT16 uStreamNumber;
  807.     UINT8 unASMFlags;
  808.     UINT16 unASMRuleNumber;
  809.     BOOL bIsLost = pPacket->IsLost();
  810.     IHXBuffer* pBuffer = NULL;
  811.     pPacket->Get(pBuffer,
  812.  ulTime,
  813.  uStreamNumber,
  814.  unASMFlags,
  815.  unASMRuleNumber);
  816.     if (pStreamData->m_pTSConverter)
  817.     {
  818. ulRTPTime = pStreamData->m_pTSConverter->hxa2rtp(ulTime);
  819.     }
  820.     else
  821.     {
  822. ulRTPTime = ulTime;
  823.     }
  824.     pRTPPacket->SetRTP(pBuffer,
  825.        ulTime,
  826.        ulRTPTime,
  827.        uStreamNumber,
  828.        unASMFlags,
  829.        unASMRuleNumber);
  830.     if (bIsLost)
  831.     {
  832. pRTPPacket->SetAsLost();
  833.     }
  834.     HX_RELEASE(pBuffer);
  835.     result = m_pResp->PacketReady(status, m_sessionID, pRTPPacket);
  836.     pRTPPacket->Release();
  837. }
  838. return result;
  839.     }
  840. }
  841.     }
  842.     else
  843.     {
  844. /*
  845.  * This is a lost packet
  846.  */
  847. if (pStreamData->m_bUsesRTPPackets)
  848. {
  849.     result = m_pCommonClassFactory->CreateInstance(
  850. CLSID_IHXRTPPacket,
  851. (void**) &pPacket);
  852. }
  853. else
  854. {
  855.     result = m_pCommonClassFactory->CreateInstance(
  856. CLSID_IHXPacket,
  857. (void**) &pPacket);
  858. }
  859.     
  860. if (pPacket)
  861. {
  862.     pPacket->Set(0, 0, pStreamData->m_streamNumber, 0, 0);
  863.     pPacket->SetAsLost();
  864.     result = m_pResp->PacketReady(status, m_sessionID, pPacket);
  865.     pPacket->Release();
  866. }
  867. return result;
  868.     }
  869.     return m_pResp->PacketReady(status, m_sessionID, pPacket);
  870. }
  871. HX_RESULT
  872. RTSPTransport::packetReady(HX_RESULT status, UINT16 uStreamNumber, IHXPacket* pPacket)
  873. {
  874.     RTSPStreamData* pStreamData = NULL;
  875.     ASSERT(!m_bIsSource);
  876.     pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
  877.     HX_ASSERT(pStreamData);
  878.     return packetReady(status, pStreamData, pPacket);
  879. }
  880. HX_RESULT
  881. RTSPTransport::getStatus
  882. (
  883.     UINT16& uStatusCode, 
  884.     IHXBuffer*& pStatusDesc, 
  885.     UINT16& ulPercentDone
  886. )
  887. {
  888. #if 0
  889.     if (!m_pStreamHandler)
  890.     {
  891. uStatusCode = HX_STATUS_INITIALIZING;
  892. pStatusDesc = 0;
  893. ulPercentDone = 0;
  894. return HXR_OK;
  895.     }
  896.     uStatusCode = HX_STATUS_READY;
  897.     pStatusDesc = 0;
  898.     ulPercentDone = 100;
  899.     RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  900.     ASSERT(pStreamData);
  901.     while(pStreamData)
  902.     {
  903. UINT16 tempStatusCode;
  904. UINT16 tempPercentDone;
  905. pStreamData->m_pTransportBuffer->GetStatus(tempStatusCode,
  906.                                            tempPercentDone);
  907. /*
  908.  * The status is always that of the stream which is least ready
  909.  */
  910. if (tempStatusCode < uStatusCode)
  911. {
  912.     uStatusCode     = tempStatusCode;
  913.     ulPercentDone   = tempPercentDone;
  914. }
  915. else if (tempStatusCode == uStatusCode && 
  916.  tempPercentDone < ulPercentDone)
  917. {
  918.     ulPercentDone = tempPercentDone;
  919. }
  920. pStreamData = m_pStreamHandler->nextStreamData();
  921.     }
  922.     return HXR_OK;
  923. #else
  924.     return HXR_NOTIMPL;
  925. #endif
  926. }
  927. HX_RESULT
  928. RTSPTransport::GetCurrentBuffering(UINT16  uStreamNumber,
  929.    INT64&  llLowestTimestamp, 
  930.    INT64&  llHighestTimestamp,
  931.    UINT32& ulNumBytes,
  932.    BOOL&   bDone)
  933. {
  934.     if (!m_pStreamHandler)
  935.     {
  936. return HXR_OK;
  937.     }
  938.     RTSPStreamData* pStreamData;
  939.     pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
  940.     HX_ASSERT(pStreamData);
  941.     return pStreamData ? 
  942.            pStreamData->m_pTransportBuffer->GetCurrentBuffering(
  943.                                             llLowestTimestamp,
  944.                                             llHighestTimestamp,
  945.                                             ulNumBytes,
  946.                                             bDone) : HXR_OK;
  947. }
  948. HX_RESULT
  949. RTSPTransport::SeekFlush(UINT16 uStreamNumber)
  950. {
  951.     if (!m_pStreamHandler)
  952.     {
  953. return HXR_OK;
  954.     }
  955.     RTSPStreamData* pStreamData;
  956.     pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
  957.     HX_ASSERT(pStreamData);
  958.     if (pStreamData)
  959.     {
  960. pStreamData->m_pTransportBuffer->SeekFlush();
  961.     }
  962.     return HXR_OK;
  963. }
  964. BOOL
  965. RTSPTransport::IsSourceDone(void)
  966. {
  967.     return m_bSourceDone;
  968. }
  969. void      
  970. RTSPTransport::CheckForSourceDone(UINT16 uStreamNumber)
  971. {
  972.     if (m_bSourceDone)
  973.     {
  974. return;
  975.     }
  976.     HX_ASSERT(m_pStreamHandler);
  977.     if (!m_pStreamHandler)
  978.     {
  979. return;
  980.     }
  981.     RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  982.     HX_ASSERT(pStreamData);
  983.     m_bSourceDone = TRUE;
  984.     while(pStreamData)
  985.     {
  986. if (pStreamData->m_streamNumber == uStreamNumber)
  987. {
  988.     pStreamData->m_bReceivedAllPackets = TRUE;
  989. }
  990. else if (!pStreamData->m_bReceivedAllPackets)
  991. {
  992.     m_bSourceDone = FALSE;
  993.     return;
  994. }
  995. pStreamData = m_pStreamHandler->nextStreamData();
  996.     }
  997.     /* We have received all the packets... Tell the reposnse object */
  998.     if (!m_bIsSource)
  999.     {
  1000. m_pResp->OnSourceDone();
  1001.     }
  1002. }    
  1003. void      
  1004. RTSPTransport::HandleBufferError()
  1005. {
  1006.     if (m_pResp)
  1007.     {
  1008. m_pResp->OnProtocolError(HXR_BUFFERING);
  1009.     }
  1010. }
  1011. RTSPResendBuffer*
  1012. RTSPTransport::getResendBuffer(UINT16 uStreamNumber)
  1013. {
  1014.     return m_pStreamHandler->getResendBuffer(uStreamNumber);
  1015. }
  1016. HX_RESULT
  1017. RTSPTransport::initializeStatistics
  1018. (
  1019.     UINT32 ulRegistryID
  1020. )
  1021. {
  1022.     m_bIsInitialized = TRUE;
  1023.     if (m_bIsSource)
  1024.     {
  1025. m_ulRegistryID = ulRegistryID;
  1026.     }
  1027.     else
  1028.     {
  1029. // XXX HP
  1030. // rather than create a new copy of STREAM_STATS, we simply
  1031. // obtain the same STREAM_STATS* from RTSPProtocol via SetStatistics().
  1032. // this could save us on both the memory and several ms during the startup
  1033. /*
  1034. IHXBuffer* pParentName = NULL;
  1035. CHAR RegKeyName[MAX_DISPLAY_NAME] = {0};
  1036. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1037. ASSERT(pStreamData);
  1038. if (!m_pRegistry)
  1039. {
  1040.     return HXR_FAIL;
  1041. }
  1042. HX_RESULT result = m_pRegistry->GetPropName(ulRegistryID, pParentName);
  1043. if (result != HXR_OK)
  1044. {
  1045.     return result;
  1046. }
  1047. // create registry entries of each stream
  1048. while (pStreamData)
  1049. {
  1050.     UINT16 uStreamNumber = pStreamData->m_streamNumber;
  1051.     sprintf(RegKeyName, "%s.Stream%d", pParentName->GetBuffer(),
  1052.                                        uStreamNumber);
  1053.     UINT32 uStreamId = m_pRegistry->GetId(RegKeyName);
  1054.     // create stream reg key if it has not been created
  1055.     // by the source yet
  1056.     if (!uStreamId)
  1057.     {
  1058. return HXR_FAIL;
  1059.     }
  1060.     pStreamData->m_pStreamStats = new STREAM_STATS(m_pRegistry,
  1061.                                                    uStreamId);
  1062.    
  1063.     pStreamData = m_pStreamHandler->nextStreamData();
  1064. }
  1065. pParentName->Release();
  1066. */
  1067.     }
  1068.     return HXR_OK;
  1069. }
  1070. HX_RESULT
  1071. RTSPTransport::SetStatistics(UINT16 uStreamNumber, STREAM_STATS* pStats)
  1072. {
  1073.     HX_RESULT     rc = HXR_OK;
  1074. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  1075.     RTSPStreamData* pStreamData = NULL;
  1076.     if (!m_pStreamHandler)
  1077.     {
  1078. rc = HXR_FAILED;
  1079. goto cleanup;
  1080.     }
  1081.     pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
  1082.     if (!pStreamData)
  1083.     {
  1084. rc = HXR_FAILED;
  1085. goto cleanup;
  1086.     }
  1087.     pStreamData->m_pStreamStats = pStats;
  1088. cleanup:
  1089. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  1090.     return rc;
  1091. }
  1092. HX_RESULT 
  1093. RTSPTransport::updateStatistics(BOOL bUseRegistry)
  1094. {
  1095.     m_bIsUpdated = TRUE;
  1096. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  1097.     if (m_bIsSource)
  1098.     {
  1099. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1100. if (!pStreamData)
  1101. {
  1102.     return HXR_FAIL;
  1103. }
  1104. /*
  1105.  * XXXGH...streams are managed by the PPM and should not show up
  1106.  *         under the transport
  1107.  */
  1108. while (pStreamData)
  1109. {
  1110.     UINT32 ulResendSuccess = 0;
  1111.     UINT32 ulResendFailure = 0;
  1112.     if (pStreamData->m_pResendBuffer)
  1113.     {
  1114. pStreamData->m_pResendBuffer->UpdateStatistics(ulResendSuccess,
  1115.                                                ulResendFailure);
  1116.     }
  1117.     m_ulTotalSuccessfulResends += ulResendSuccess;
  1118.     m_ulTotalFailedResends += ulResendFailure;
  1119.     pStreamData = m_pStreamHandler->nextStreamData();
  1120. }
  1121.         m_ulSendingTime = CALCULATE_ELAPSED_TICKS(m_ulStartTime, HX_GET_TICKCOUNT()) / 1000;
  1122. IHXBuffer* pName;
  1123. if (bUseRegistry
  1124.         &&  m_pRegistry 
  1125.         &&  HXR_OK == m_pRegistry->GetPropName(m_ulRegistryID, pName))
  1126. {
  1127.     char str[512]; /* Flawfinder: ignore */
  1128.     const char* name = (const char*)pName->GetBuffer();
  1129.     char pTemp[32]; /* Flawfinder: ignore */
  1130.     i64toa(m_lBytesSent, pTemp, 10);
  1131.     sprintf(str, "%-.400s.PacketsSent", name); /* Flawfinder: ignore */
  1132.     m_pRegistry->AddInt(str, m_ulPacketsSent);
  1133.     sprintf(str, "%-.400s.BytesSent", name); /* Flawfinder: ignore */
  1134.     m_pRegistry->AddInt(str, INT64_TO_INT32(m_lBytesSent));
  1135.     // Add the total bytes sent as a string because we don't want
  1136.     // to have to truncate the INT64 value that is storing it
  1137.     sprintf(str, "%-.400s.TotalBytesSent", name); /* Flawfinder: ignore */
  1138.     IHXBuffer* pBuffer = new CHXBuffer();
  1139.     pBuffer->AddRef();
  1140.     pBuffer->Set((UCHAR*)pTemp, strlen(pTemp) + 1);
  1141.     m_pRegistry->AddStr(str, pBuffer);
  1142.     HX_RELEASE(pBuffer);
  1143.     sprintf(str, "%-.400s.SendingTime", name); /* Flawfinder: ignore */
  1144.     m_pRegistry->AddInt(str, m_ulSendingTime); 
  1145.     sprintf(str, "%-.400s.ResendSuccess", name); /* Flawfinder: ignore */
  1146.     m_pRegistry->AddInt(str, m_ulTotalSuccessfulResends);
  1147.     sprintf(str, "%-.400s.ResendFailure", name); /* Flawfinder: ignore */
  1148.     m_pRegistry->AddInt(str, m_ulTotalFailedResends);
  1149.     pName->Release();
  1150. }
  1151.     }
  1152.     else
  1153.     {
  1154. ULONG32 ulNormal = 0;
  1155. ULONG32 ulReceived = 0;
  1156. ULONG32 ulLost = 0;
  1157. ULONG32 ulLate = 0;
  1158. ULONG32 ulTotal = 0;
  1159. ULONG32 ulResendRequested = 0;
  1160. ULONG32 ulResendReceived = 0;
  1161. ULONG32 ulAvgBandwidth = 0;
  1162. ULONG32 ulCurBandwidth = 0;
  1163. UINT32 ulTotal30 = 0;
  1164. UINT32 ulLost30 = 0;
  1165. UINT32  ulDuplicate = 0;
  1166. UINT32 ulOutOfOrder = 0;
  1167. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1168. if (!pStreamData)
  1169. {
  1170.     return HXR_FAIL;
  1171. }
  1172. while (pStreamData)
  1173. {
  1174.     STREAM_STATS* pStreamStats = pStreamData->m_pStreamStats;
  1175.             if (!pStreamStats || !pStreamStats->m_bInitialized)
  1176.     {
  1177. goto updateContinue;
  1178.     }
  1179.     pStreamData->m_pTransportBuffer->UpdateStatistics(ulNormal,
  1180.                                                       ulLost,
  1181.                                                       ulLate,
  1182.                                                       ulResendRequested,
  1183.                                                       ulResendReceived,
  1184.                                                       ulAvgBandwidth,
  1185.                                                       ulCurBandwidth,
  1186.       ulTotal30,
  1187.       ulLost30,
  1188.       ulDuplicate,
  1189.       ulOutOfOrder);
  1190.                   
  1191.     ulReceived = ulNormal + ulResendReceived;
  1192.     ulTotal = ulReceived + ulLost + ulLate;
  1193.     pStreamStats->m_pNormal->SetInt((INT32)ulNormal);
  1194.     pStreamStats->m_pRecovered->SetInt((INT32)ulResendReceived);
  1195.     pStreamStats->m_pReceived->SetInt((INT32)ulReceived);
  1196.     pStreamStats->m_pLost->SetInt((INT32)ulLost);
  1197.     pStreamStats->m_pLate->SetInt((INT32)ulLate);
  1198.     pStreamStats->m_pDuplicate->SetInt((INT32)ulDuplicate);
  1199.     pStreamStats->m_pOutOfOrder->SetInt((INT32)ulOutOfOrder);
  1200.     pStreamStats->m_pTotal->SetInt((INT32)ulTotal);
  1201.     pStreamStats->m_pLost30->SetInt((INT32)ulLost30);
  1202.     pStreamStats->m_pTotal30->SetInt((INT32)ulTotal30);
  1203.     pStreamStats->m_pResendRequested->SetInt((INT32)ulResendRequested);
  1204.     pStreamStats->m_pResendReceived->SetInt((INT32)ulResendReceived);
  1205.     pStreamStats->m_pAvgBandwidth->SetInt((INT32)ulAvgBandwidth);
  1206.     pStreamStats->m_pCurBandwidth->SetInt((INT32)ulCurBandwidth);
  1207. updateContinue:
  1208.     pStreamData = m_pStreamHandler->nextStreamData();
  1209. }
  1210.     }
  1211. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  1212.     return HXR_OK;
  1213. }
  1214. HX_RESULT 
  1215. RTSPTransport::UpdateRegistry(UINT32 ulStreamNumber,
  1216.       UINT32 ulRegistryID)
  1217. {
  1218.     if (m_bIsSource)
  1219.     {
  1220. m_ulRegistryID = ulRegistryID;
  1221.     }
  1222.     else
  1223.     {
  1224. // XXX HP
  1225. // rather than create a new copy of STREAM_STATS, we simply
  1226. // obtain the same STREAM_STATS* from RTSPProtocol via SetStatistics().
  1227. // this could save us on both the memory and several ms during the startup
  1228. /*
  1229. if (!m_pRegistry)
  1230. {
  1231.     return HXR_FAIL;
  1232. }
  1233. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1234. while (pStreamData)
  1235. {
  1236.     if (pStreamData->m_streamNumber == (UINT16)ulStreamNumber)
  1237.     {
  1238. HX_DELETE(pStreamData->m_pStreamStats);
  1239. pStreamData->m_pStreamStats = new STREAM_STATS(m_pRegistry,
  1240.        ulRegistryID);
  1241. break;
  1242.     }    
  1243.     pStreamData = m_pStreamHandler->nextStreamData();
  1244. }
  1245. */
  1246.     }
  1247.     return HXR_OK;
  1248. }
  1249. RTSPTransportBuffer*
  1250. RTSPTransport::getTransportBuffer(UINT16 uStreamNumber)
  1251. {
  1252.     if (!m_pStreamHandler)
  1253.     {
  1254. return NULL;
  1255.     }
  1256.     RTSPStreamData* pStreamData;     
  1257.     pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
  1258.     if (!pStreamData)
  1259.     {
  1260. return NULL;
  1261.     }
  1262.     return pStreamData->m_pTransportBuffer;
  1263. }
  1264. HX_RESULT
  1265. RTSPTransport::playReset()
  1266. {
  1267.     m_bSourceDone = FALSE;
  1268.     if(m_pStreamHandler)
  1269.     {
  1270. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1271. while(pStreamData)
  1272. {
  1273.     if (m_bIsSource)
  1274.     {
  1275. pStreamData->m_packetSent = FALSE;
  1276.     }
  1277.     else
  1278.     {
  1279. pStreamData->m_pTransportBuffer->Reset();
  1280. pStreamData->m_bReceivedAllPackets = FALSE;
  1281.     }
  1282.     pStreamData = m_pStreamHandler->nextStreamData();
  1283. }
  1284.     }
  1285.     return HXR_OK;
  1286. }
  1287. HX_RESULT
  1288. RTSPTransport::pauseBuffers()
  1289. {
  1290.     if (m_pStreamHandler)
  1291.     {
  1292. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1293. ASSERT(pStreamData);
  1294. while(pStreamData)
  1295. {
  1296.     pStreamData->m_pTransportBuffer->Pause();
  1297.     pStreamData = m_pStreamHandler->nextStreamData();
  1298. }
  1299.     }
  1300.     return HXR_OK;
  1301. }
  1302. HX_RESULT
  1303. RTSPTransport::resumeBuffers()
  1304. {
  1305.     m_bIsReceivedData = FALSE;
  1306.     if (m_pStreamHandler)
  1307.     {
  1308. RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1309. ASSERT(pStreamData);
  1310. while(pStreamData)
  1311. {
  1312.     pStreamData->m_pTransportBuffer->Resume();
  1313.     pStreamData = m_pStreamHandler->nextStreamData();
  1314. }
  1315.     }
  1316.     return HXR_OK;
  1317. }
  1318. HX_RESULT
  1319. RTSPTransport::setFirstSeqNum(UINT16 uStreamNumber, UINT16 uSeqNum)
  1320. {
  1321.     RTSPStreamData* pStreamData;
  1322.     pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
  1323.     if(pStreamData)
  1324.     {
  1325. if (m_bIsSource)
  1326. {     
  1327.     pStreamData->m_seqNo = uSeqNum;
  1328.     if(pStreamData->m_pResendBuffer)
  1329.     {
  1330. pStreamData->m_pResendBuffer->SetFirstSequenceNumber(uSeqNum);
  1331.     }
  1332. }
  1333. else
  1334. {
  1335.     if (!pStreamData->m_pTransportBuffer)
  1336.     {
  1337. return HXR_FAIL;
  1338.     }
  1339.     if (!m_bMulticast)
  1340.     {
  1341. pStreamData->m_lastSeqNo = uSeqNum;
  1342.      pStreamData->m_pTransportBuffer->Init(uSeqNum);
  1343.     }
  1344. }
  1345.     }
  1346.     return HXR_OK;
  1347. }
  1348. HX_RESULT
  1349. RTSPTransport::Init(IUnknown* pContext)
  1350. {
  1351.     HX_RESULT hresult;
  1352.     
  1353.     if (!m_pContext)
  1354.     {
  1355. m_pContext = pContext;
  1356. m_pContext->AddRef();
  1357.     }
  1358.     hresult = pContext->QueryInterface(IID_IHXCommonClassFactory,
  1359.        (void**)&m_pCommonClassFactory);
  1360.     if (HXR_OK != hresult)
  1361.     {
  1362. return hresult;
  1363.     }
  1364.     
  1365.     hresult = pContext->QueryInterface(IID_IHXScheduler,
  1366.                                        (void**)&m_pScheduler);
  1367.     if (HXR_OK != hresult)
  1368.     {
  1369. DPRINTF(D_INFO, ("could not get scheduler...n"));
  1370. return hresult;
  1371.     }
  1372.     pContext->QueryInterface(IID_IHXRegistry, (void**)&m_pRegistry);
  1373.     pContext->QueryInterface(IID_IHXInternalReset,
  1374.                                (void**)&m_pInternalReset);
  1375.     pContext->QueryInterface(IID_IHXPlayerState,
  1376.                                (void**)&m_pPlayerState);
  1377.     pContext->QueryInterface(IID_IHXSourceBufferingStats2,
  1378.      (void**)&m_pSrcBufferStats);
  1379. #ifdef RDT_MESSAGE_DEBUG
  1380.     IHXPreferences* pPreferences = NULL;
  1381.     
  1382.     if (pContext &&
  1383. (HXR_OK == pContext->QueryInterface(IID_IHXPreferences,
  1384.                                             (void**) &pPreferences)))
  1385.     {
  1386. IHXBuffer* pBuffer = NULL;
  1387.         ReadPrefBOOL(pPreferences, "RDTMessageDebug", m_bRDTMessageDebug);
  1388. if (m_bRDTMessageDebug)
  1389. {
  1390.     if (HXR_OK == pPreferences->ReadPref("RDTMessageDebugFile", pBuffer))
  1391.     {
  1392. if (pBuffer->GetSize() <= 0)
  1393. {
  1394.     // no file name, no log
  1395.     m_bRDTMessageDebug = FALSE;
  1396. }
  1397. else
  1398. {
  1399.     m_RDTmessageDebugFileName = (const char*) pBuffer->GetBuffer();
  1400. }
  1401.     }
  1402.             HX_RELEASE(pBuffer);
  1403. }
  1404.     }
  1405.     HX_RELEASE(pPreferences);
  1406. #endif // RDT_MESSAGE_DEBUG
  1407.     
  1408.     return HXR_OK;
  1409. }
  1410. HX_RESULT
  1411. RTSPTransport::SetResendBufferDepth(UINT32 uMilliseconds)
  1412. {
  1413.     RTSPStreamData* pStreamData = m_pStreamHandler->firstStreamData();
  1414.     ASSERT(pStreamData);
  1415.     while (pStreamData)
  1416.     {
  1417. if (m_bIsSource)
  1418. {
  1419.     if (pStreamData->m_pResendBuffer)
  1420.     {
  1421. pStreamData->m_pResendBuffer->SetBufferDepth(uMilliseconds);
  1422.     }
  1423. }
  1424. else
  1425. {
  1426.     if (pStreamData->m_pTransportBuffer)
  1427.     {
  1428. pStreamData->m_pTransportBuffer->SetBufferDepth(uMilliseconds);
  1429.     }
  1430. }
  1431. pStreamData = m_pStreamHandler->nextStreamData();
  1432.     }
  1433.     return HXR_OK;
  1434. }
  1435. #ifdef RDT_MESSAGE_DEBUG
  1436. void RTSPTransport::RDTmessageFormatDebugFileOut(const char* fmt, ...)
  1437. {
  1438.     if(m_bRDTMessageDebug)
  1439.     {
  1440.         char buf[4096]; /* Flawfinder: ignore */
  1441. va_list args;
  1442. va_start(args, fmt);
  1443. FILE* fp = fopen((const char*)m_RDTmessageDebugFileName, "a");
  1444. if (fp)
  1445. {
  1446.     vsprintf(buf, fmt, args);
  1447.     fprintf(fp, "%sn", buf);
  1448.     fclose(fp);
  1449. }
  1450. va_end(args);
  1451.     }
  1452. }
  1453. #endif // RDT_MESSAGE_DEBUG