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

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  *  Defines
  37.  */
  38. /****************************************************************************
  39.  *  Includes
  40.  */
  41. #include "hxcom.h"
  42. #include "rtpclsnc.h"
  43. #include "ihxpckts.h"
  44. #include "rtspif.h"
  45. #include "ntptime.h"
  46. /****************************************************************************
  47.  *  CRTPClientStreamSync             
  48.  */
  49. /****************************************************************************
  50.  *  Constructor/Destructor          
  51.  */
  52. CRTPClientStreamSync::CRTPClientStreamSync(void)
  53.     : m_pTSConverter(NULL)
  54.     , m_bIsImportedTSConverter(FALSE)
  55.     , m_bIsSyncMaster(FALSE)
  56.     , m_bStartSyncSet(FALSE)
  57.     , m_bIsStronglySynced(FALSE)
  58.     , m_bNTPtoHXOffsetSet(FALSE)
  59.     , m_lNTPtoHXOffset(0)
  60.     , m_lTimeOffsetRTP(0)
  61.     , m_lTimeOffsetHX(0)
  62.     , m_lSyncOffsetRTP(0)
  63.     , m_lSyncOffsetHX(0)
  64.     , m_lOffsetToMasterRTP(0)
  65.     , m_lOffsetToMasterHX(0)
  66.     , m_bStartTimeSet(FALSE)
  67.     , m_ulStartTime(0)
  68.     , m_pSyncServer(NULL)
  69.     , m_ulAcceptableSyncNoise(RTPCL_ACCEPTABLE_SYNC_NOISE)
  70. {
  71.     ;
  72. }
  73. CRTPClientStreamSync::~CRTPClientStreamSync(void)
  74. {
  75.     Close();
  76. }
  77. /****************************************************************************
  78.  *  Main Interface               
  79.  */
  80. /****************************************************************************
  81.  *  CRTPClientStreamSync::Init              
  82.  */
  83. HX_RESULT CRTPClientStreamSync::Init(ULONG32 ulHXAFactor,
  84.      ULONG32 ulRTPFactor,
  85.      IHXTransportSyncServer* pSyncServer,
  86.      BOOL bIsSyncMaster,
  87.      ULONG32 ulAcceptableSyncNoise)
  88. {
  89.     HX_RESULT retVal = HXR_OK;
  90.     ReleaseTSConverter();
  91.     HX_RELEASE(m_pSyncServer);
  92.     Reset();
  93.     m_ulAcceptableSyncNoise = ulAcceptableSyncNoise;
  94.     m_bIsSyncMaster = bIsSyncMaster;
  95.     m_pSyncServer = pSyncServer;
  96.     if (m_pSyncServer)
  97.     {
  98. m_pSyncServer->AddRef();
  99.     }
  100.     retVal = HXR_OUTOFMEMORY;
  101.     m_pTSConverter = new CHXTimestampConverter(CHXTimestampConverter::FACTORS,
  102.        ulHXAFactor, 
  103.        ulRTPFactor);
  104.     if (m_pTSConverter)
  105.     {
  106. retVal = HXR_OK;
  107.     }
  108.     return retVal;
  109. }
  110.     
  111. HX_RESULT CRTPClientStreamSync::Init(CHXTimestampConverter* pTSConverter,
  112.      IHXTransportSyncServer* pSyncServer,
  113.      BOOL bIsSyncMaster,
  114.      ULONG32 ulAcceptableSyncNoise)
  115. {
  116.     HX_RESULT retVal = HXR_OK;
  117.     ReleaseTSConverter();
  118.     HX_RELEASE(m_pSyncServer);
  119.     Reset();
  120.     m_ulAcceptableSyncNoise = ulAcceptableSyncNoise;
  121.     m_bIsSyncMaster = bIsSyncMaster;
  122.     m_pSyncServer = pSyncServer;
  123.     if (m_pSyncServer)
  124.     {
  125. m_pSyncServer->AddRef();
  126.     }
  127.     m_pTSConverter = pTSConverter;
  128.     if (m_pTSConverter)
  129.     {
  130. m_bIsImportedTSConverter = TRUE;
  131.     }
  132.     return retVal;
  133. }
  134. /****************************************************************************
  135.  *  CRTPClientStreamSync::Close               
  136.  */
  137. void CRTPClientStreamSync::Close(void)
  138. {
  139.     ReleaseTSConverter();
  140.     HX_RELEASE(m_pSyncServer);
  141. }
  142. /****************************************************************************
  143.  *  CRTPClientStreamSync::Reset               
  144.  */
  145. void CRTPClientStreamSync::Reset(void)
  146. {
  147.     m_bStartSyncSet = FALSE;
  148.     m_bIsStronglySynced = FALSE;
  149.     m_bNTPtoHXOffsetSet = FALSE;
  150.     m_lNTPtoHXOffset = 0;
  151.     m_lTimeOffsetRTP = 0;
  152.     m_lTimeOffsetHX = 0;
  153.     m_lSyncOffsetHX = 0;
  154.     m_lSyncOffsetRTP = 0;
  155.     m_lOffsetToMasterHX = 0;
  156.     m_lOffsetToMasterRTP = 0;
  157.     m_bStartTimeSet = FALSE;
  158.     m_ulStartTime = 0;
  159.     if (m_pTSConverter)
  160.     {
  161. m_pTSConverter->ReInit(m_pTSConverter->GetConversionFactors());
  162.     }
  163. }
  164. /****************************************************************************
  165.  *  CRTPClientStreamSync::SetStartTime 
  166.  *
  167.  *  Establishes the reference starting time (in ms) of the session to be used
  168.  *  for computation of individual initial stream syncronization offsets in
  169.  *  case the stream RTP-NPT time is not explictly provided (e.g. via rtp-info
  170.  *  in PLAY response).
  171.  *  This function can be called multiple times by various streams in the
  172.  *  the session.  However, only the first setting will take effect and will
  173.  *  be reflected to all other streams.
  174.  * ulRefHXStartTime     - reference starting time (in ms) of a session
  175.  *         (normally this is the reference arrival time
  176.  *  of the first packet of the stream)
  177.  * bAsSecondaryRecepient - TRUE =  called as reaction of some other stream
  178.  *         establishing the sessions reference
  179.  *         start time and thus reflection to other 
  180.  *         streams in the session should not be
  181.  *         attempted
  182.  * FALSE = stream initiated establishing of the 
  183.  * sessions reference start time and thus
  184.  * the reflection of the start time to
  185.  * all streams in the session is to be
  186.  * attempted        
  187.  */
  188. HX_RESULT CRTPClientStreamSync::SetStartTime(ULONG32 ulRefHXStartTime,
  189.      BOOL bAsSecondaryRecipient)
  190. {
  191.     HX_RESULT retVal = HXR_UNEXPECTED;
  192.     if (!m_bStartSyncSet)
  193.     {
  194. retVal = HXR_IGNORE;
  195. if (!m_bStartTimeSet)
  196. {
  197.     retVal = HXR_OK;
  198.     if (bAsSecondaryRecipient)
  199.     {
  200. m_bStartTimeSet = TRUE;
  201. m_ulStartTime = ulRefHXStartTime;
  202.     }
  203.     else
  204.     {
  205. if (m_pSyncServer)
  206. {
  207.     retVal = m_pSyncServer->DistributeStartTime(
  208. ulRefHXStartTime);
  209. }
  210.     }
  211. }
  212.     }
  213.     return retVal;
  214. }
  215. /****************************************************************************
  216.  *  CRTPClientStreamSync::SetStartSync    
  217.  *
  218.  *  Establishes intial synchronization of the stream relative to other
  219.  *  streams.  This method must be called to enable the syncronization
  220.  *  functionality of this class.
  221.  * ulRTPTime         - stream RTP time in vicinity of the first RTP time
  222.  *             stamp received for the stream, corresponding to
  223.  *     the passed in RMA time (in RTP units)
  224.  * ulHXTime         - stream NPT time corresponding to the passed in
  225.  *     RTP time (in ms)
  226.  *      bIsNominalHXTime - FALSE = binding between RTP and NPT is exact
  227.  *     (This normally means that RTP-NPT mapping
  228.  *      was explictly provided through out of
  229.  *      band means such as rtp-info in PLAY
  230.  *      response)
  231.  *     TRUE  = binding between RTP and NPT is loose
  232.  *     (This normally means that RTP-NPT mapping
  233.  *      was NOT explictly provided through out of
  234.  *      band means such as rtp-info in PLAY
  235.  *      response. In such case offset between
  236.  *      streams will be established using the
  237.  *      difference in arrival time of the first 
  238.  *      stream packets - if supplied to this
  239.  *      class.)
  240.  * ulRefHXStartTime - reference time value in ms representing the arrival
  241.  *     time of the packet corresponding to the passed in
  242.  *     RTP time.  This value must be properly set if
  243.  *     bIsNominalHXTime == TRUE and SetStartTime() method
  244.  *     was invoked on any of the streams in the session.
  245.  *     This value is used to compute the initial
  246.  *     synchronization offset of the stream based on the
  247.  *     packet arrival time when RTP-NPT mapping is not
  248.  *     explicitly communicated 
  249.  *     (bIsNominalHXTime == TRUE).
  250.  */
  251. HX_RESULT CRTPClientStreamSync::SetStartSync(ULONG32 ulRTPTime,
  252.      ULONG32 ulHXTime,
  253.      BOOL bIsNominalHXTime,
  254.      ULONG32 ulRefHXStartTime)
  255. {
  256.     HX_RESULT retVal = HXR_UNEXPECTED;
  257.     if (!m_bIsStronglySynced)
  258.     {
  259. LONG32 lHXTimeAdjustment = 0;
  260. retVal = HXR_OK;
  261. m_bStartSyncSet = TRUE;
  262. m_bIsStronglySynced = (!bIsNominalHXTime);
  263. if (bIsNominalHXTime && m_bStartTimeSet)
  264. {
  265.     lHXTimeAdjustment = ((LONG32) 
  266. (ulRefHXStartTime - m_ulStartTime));
  267. }
  268. if (m_pTSConverter)
  269. {
  270.     m_lTimeOffsetRTP = ulRTPTime - 
  271.        m_pTSConverter->hxa2rtp_raw(ulHXTime + lHXTimeAdjustment);
  272.     m_pTSConverter->setAnchor(ulHXTime + lHXTimeAdjustment, 
  273.       ulRTPTime);
  274.     m_lTimeOffsetHX = 0;
  275. }
  276. else
  277. {
  278.     m_lTimeOffsetHX = m_lTimeOffsetRTP = 
  279. (ulRTPTime - ulHXTime - lHXTimeAdjustment);
  280. }
  281.     }
  282.     return retVal;
  283. }
  284. /****************************************************************************
  285.  *  CRTPClientStreamSync::HandleMasterSync     
  286.  *
  287.  *  Incorporates the synchronization adjustment as requested by the master
  288.  *  syncronization stream.  Master synchronization stream (usally audio stream)
  289.  *  does not adjust its time-line but rather reflects its adjustment to all
  290.  *  other streams.  This is normally done to avoid gaps or clipping in audio.
  291.  * ulHXTime   - NPT (Normal Play time) of the master sync. stream when
  292.  *       the synchronization adjustemnt of slave streams was
  293.  *       requested (in ms)
  294.  * lHXOffsetToMaster - time offset from master stream to apply (in ms)
  295.  */
  296. HX_RESULT CRTPClientStreamSync::HandleMasterSync(ULONG32 ulHXTime, 
  297.  LONG32 lHXOffsetToMaster)
  298. {
  299.     HX_RESULT retVal = HXR_IGNORE;
  300.     if (!m_bIsSyncMaster)
  301.     {
  302. retVal = HXR_OK;
  303. m_lOffsetToMasterHX = lHXOffsetToMaster;
  304. if (lHXOffsetToMaster >= 0)
  305. {
  306.     m_lOffsetToMasterRTP = (LONG32) 
  307. (m_pTSConverter->hxa2rtp_raw((ULONG32) lHXOffsetToMaster));
  308. }
  309. else
  310. {
  311.     m_lOffsetToMasterRTP = (LONG32) 
  312. (-m_pTSConverter->hxa2rtp_raw((ULONG32) (-lHXOffsetToMaster)));
  313. }
  314.     }
  315.     return retVal;
  316. }
  317. /****************************************************************************
  318.  *  CRTPClientStreamSync::AnchorSync
  319.  *
  320.  *  Establishes the mapping between NPT (Normal play time) and NTP time.
  321.  *  This relationship is needed before RTCP reported (NTP,RTP) time stamp
  322.  *  pairs can be applied to synchronization.  This mapping is common for
  323.  *  all streams in the session and is normally established by reception
  324.  *  of the first RTCP packet after the starting stream synchronization is
  325.  *  known (or is estimated).
  326.  * ulHXTime    - NPT time corresponding to passed in NTP time
  327.  * ulNTPHXTime - NTP time in ms corresponding to passed in NPT time
  328.  */
  329. HX_RESULT CRTPClientStreamSync::AnchorSync(ULONG32 ulHXTime, 
  330.    ULONG32 ulNTPHXTime)
  331. {
  332.     HX_RESULT retVal = HXR_OK;
  333.     m_lNTPtoHXOffset = ulHXTime - ulNTPHXTime;
  334.     m_bNTPtoHXOffsetSet = TRUE;
  335.     return retVal;
  336. }
  337. /****************************************************************************
  338.  *  CRTPClientStreamSync::HandleRTCPSync    
  339.  *
  340.  *  Incorporates the NTP and RTP time stamp relationships reported by RTCP
  341.  *  into synchronization equation.
  342.  * ntpTime   - RTCP reported NTP time
  343.  * ulRTPTime - RTCP reported RTP time
  344.  */
  345. HX_RESULT CRTPClientStreamSync::HandleRTCPSync(NTPTime ntpTime, 
  346.        ULONG32 ulRTPTime)
  347. {
  348.     HX_RESULT retVal = HXR_IGNORE;
  349.     ULONG32 ulNtpHX = ntpTime.toMSec();
  350.     
  351.     // We ignore the RTCP sync until we can compute npt (m_bStartSyncSet) or
  352.     // if the RTCP packet contains no synchronization information 
  353.     // (ulNtpHX == 0)
  354.     if ((ulNtpHX != 0) && m_bStartSyncSet)
  355.     {
  356. // Npt time can be computed (ulHXTime)
  357. ULONG32 ulHXTime = m_pTSConverter->rtp2hxa(ulRTPTime);
  358. retVal = HXR_OK;
  359. if (m_bNTPtoHXOffsetSet)
  360. {
  361.     // We can sync - NTP to NPT offset is known
  362.     ULONG32 ulExpectedHXTime = ulNtpHX + m_lNTPtoHXOffset;
  363.     LONG32 lSyncOffsetHX = ulExpectedHXTime - ulHXTime;
  364.     LONG32 lSyncOffsetChange = lSyncOffsetHX - m_lSyncOffsetHX;
  365.     
  366.     if (((ULONG32)lSyncOffsetChange > m_ulAcceptableSyncNoise) ||
  367. (lSyncOffsetChange < (LONG32)(-m_ulAcceptableSyncNoise)))
  368.     {
  369. if (m_bIsSyncMaster && m_pSyncServer)
  370. {
  371.     m_pSyncServer->DistributeSync(ulHXTime, -lSyncOffsetHX);
  372. }
  373. else
  374. {     
  375.     m_lSyncOffsetHX = lSyncOffsetHX;
  376.     if (lSyncOffsetHX >= 0)
  377.     {
  378. m_lSyncOffsetRTP = (LONG32) 
  379.     (m_pTSConverter->hxa2rtp_raw((ULONG32) lSyncOffsetHX));
  380.     }
  381.     else
  382.     {
  383. m_lSyncOffsetRTP = (LONG32) 
  384.     (-m_pTSConverter->hxa2rtp_raw((ULONG32) (-lSyncOffsetHX)));
  385.     }
  386. }
  387.     }
  388.     m_bIsStronglySynced = TRUE;
  389. }
  390. else
  391. {
  392.     // This the first RTCP sync accross all streams, anchor sync
  393.     if (m_pSyncServer)
  394.     {
  395. m_pSyncServer->DistributeSyncAnchor(ulHXTime, ulNtpHX);
  396.     }
  397. }
  398.     }
  399.     return retVal;
  400. }
  401. /****************************************************************************
  402.  *  Private Methods             
  403.  */
  404. /****************************************************************************
  405.  *  CRTPClientStreamSync::ReleaseTSConverter               
  406.  */
  407. void CRTPClientStreamSync::ReleaseTSConverter(void)
  408. {
  409.     if (m_bIsImportedTSConverter)
  410.     {
  411. m_pTSConverter = NULL;
  412.     }
  413.     else
  414.     {
  415. HX_DELETE(m_pTSConverter);
  416.     }
  417.     m_bIsImportedTSConverter = FALSE;
  418. }