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

Symbian

开发平台:

Visual C++

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