📄 rtcpmisc.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: rtcpmisc.cpp,v 1.2.36.1 2004/07/19 21:04:16 hubbe Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** */#include <stdlib.h>#include "hxtypes.h"#include "hxresult.h" // for HX_RESULT#include "hxcom.h" // for REF() macro#include "rtppkt.h" // for SDESItem#include "rtpwrap.h" // for RTCPPacket#include "ihxpckts.h" // for IHXBuffer#include "chxpckts.h" // for CHXHeader#include "asmrulep.h" // for ASMRuleBook#include "rtcpmisc.h"#include "hxheap.h"#ifdef _DEBUG#undef HX_THIS_FILE static char HX_THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////////// Class to calculate RTCP interval //CRTCPInterval::CRTCPInterval() : m_rtcp_bw(1) , m_avg_rtcp_size(128){ /* not used */ HX_ASSERT(FALSE);}CRTCPInterval::CRTCPInterval(UINT32 ulSessionBW) : m_rtcp_bw(ulSessionBW * 0.05) , m_avg_rtcp_size(128) , m_ulLastRTCPTime(0) , m_ulNextRTCPTime(0) , m_ulLastNumMembers(1) , m_ulCurNumMembers(1) , m_ulCurNumSenders(0) , m_bInitial(TRUE) , m_bWeSent(FALSE){ HX_ASSERT(0 != m_rtcp_bw); if (0 == m_rtcp_bw) { m_rtcp_bw = 1; }}CRTCPInterval::~CRTCPInterval(){ /* empty */}doubleCRTCPInterval::GetRTCPInterval(double rtcp_bw, INT32 nMembers, INT32 nSenders){ // if rtcp_bw is passed as 0.0, then just use the rtcp_bw we had. if (0.0 == rtcp_bw) { rtcp_bw = m_rtcp_bw; }/** Taken from RFC 1889 Appendix A.7 */ /* * Minimum time between RTCP packets from this site (in seconds). * This time prevents the reports from `clumping' when sessions * are small and the law of large numbers isn't helping to smooth * out the traffic. It also keeps the report interval from * becoming ridiculously small during transient outages like a * network partition. */ double const RTCP_MIN_TIME = 5.0; /* * Fraction of the RTCP bandwidth to be shared among active * senders. (This fraction was chosen so that in a typical * session with one or two active senders, the computed report * time would be roughly equal to the minimum report time so that * we don't unnecessarily slow down receiver reports.) The * receiver fraction must be 1 - the sender fraction. */ double const RTCP_SENDER_BW_FRACTION = 0.25; double const RTCP_RCVR_BW_FRACTION = (1-RTCP_SENDER_BW_FRACTION); /* * Gain (smoothing constant) for the low-pass filter that * estimates the average RTCP packet size (see Cadzow reference). */ double const RTCP_SIZE_GAIN = (1.0/16.0); double t; /* interval */ double rtcp_min_time = RTCP_MIN_TIME;// double rtcp_bw = ((double)m_ulSessionBW * 1000. * 0.05); int n = nMembers + nSenders;/* no. of members for computation */ /* * Very first call at application start-up uses half the min * delay for quicker notification while still allowing some time * before reporting for randomization and to learn about other * sources so the report interval will converge to the correct * interval more quickly. The average RTCP size is initialized * to 128 octets which is conservative (it assumes everyone else * is generating SRs instead of RRs: 20 IP + 8 UDP + 52 SR + 48 * SDES CNAME). */ if (m_bInitial) { rtcp_min_time /= 2;// m_avg_rtcp_size = 128; } /* * If there were active senders, give them at least a minimum * share of the RTCP bandwidth. Otherwise all participants share * the RTCP bandwidth equally. */ if (nSenders > 0 && nSenders < n * RTCP_SENDER_BW_FRACTION) { rtcp_bw *= RTCP_RCVR_BW_FRACTION; n -= nSenders; } /* * Update the average size estimate by the size of the report * packet we just sent. */// m_avg_rtcp_size += (cbLastPacket - m_avg_rtcp_size)*RTCP_SIZE_GAIN; /* * The effective number of sites times the average packet size is * the total number of octets sent when each site sends a report. * Dividing this by the effective bandwidth gives the time * interval over which those packets must be sent in order to * meet the bandwidth target, with a minimum enforced. In that * time interval we send one report so this time is also our * average time between reports. */ t = m_avg_rtcp_size * n / rtcp_bw; if (t < rtcp_min_time) t = rtcp_min_time; /* * To avoid traffic bursts from unintended synchronization with * other sites, we then pick our actual next report interval as a * random number uniformly distributed between 0.5*t and 1.5*t. */ return t * (((double)rand() / (double)RAND_MAX) + 0.5);}///////////////////////////////////////////////////////////////////////////////// Class for SDES//CSDES::CSDES() : m_pCName(NULL) , m_pName(NULL) , m_pTool(NULL) , m_pEmail(NULL){}CSDES::CSDES(REF(IHXBuffer*)pCName, REF(IHXBuffer*)pName, REF(IHXBuffer*)pTool, REF(IHXBuffer*)pEmail) : m_pCName(pCName) , m_pName(pName) , m_pTool(pTool) , m_pEmail(pEmail){ if (m_pCName)m_pCName->AddRef(); if (m_pName) m_pName->AddRef(); if (m_pTool) m_pTool->AddRef(); if (m_pEmail) m_pEmail->AddRef();}CSDES::~CSDES(){ HX_RELEASE(m_pCName); HX_RELEASE(m_pName); HX_RELEASE(m_pTool); HX_RELEASE(m_pEmail); }HX_RESULTCSDES::MakeSDES(REF(RTCPPacket) pktSDES, UINT32 ulSrcID){ pktSDES.version_flag = 0x02; pktSDES.padding_flag = 0; pktSDES.count = 1; pktSDES.packet_type = RTCP_SDES; pktSDES.rr_ssrc = ulSrcID; UINT16 cbItems = 0; if (m_pCName != NULL) { SDESItem item; item.sdes_type = SDES_CNAME; item.length = m_pCName->GetSize() <= UCHAR_MAX ? (UINT8)m_pCName->GetSize() -1: UCHAR_MAX; item.data = m_pCName->GetBuffer(); pktSDES.AddSDESItem(ulSrcID, item); cbItems += item.length + 2; } else { HX_ASSERT(FALSE && "Need CNAME to send reception report"); return HXR_FAIL; } if (m_pName != NULL) { SDESItem item; item.sdes_type = SDES_NAME; item.length = m_pName->GetSize() <= UCHAR_MAX ? (UINT8)m_pName->GetSize() -1: UCHAR_MAX; item.data = m_pName->GetBuffer(); pktSDES.AddSDESItem(ulSrcID, item); cbItems += item.length + 2; } if (m_pTool != NULL) { SDESItem item; item.sdes_type = SDES_TOOL; item.length = m_pTool->GetSize() <= UCHAR_MAX ? (UINT8)m_pTool->GetSize() -1: UCHAR_MAX; item.data = m_pTool->GetBuffer(); pktSDES.AddSDESItem(ulSrcID, item); cbItems += item.length + 2; } if (m_pEmail != NULL) { SDESItem item; item.sdes_type = SDES_EMAIL; item.length = m_pEmail->GetSize() <= UCHAR_MAX ? (UINT8)m_pEmail->GetSize() -1: UCHAR_MAX; item.data = m_pEmail->GetBuffer(); pktSDES.AddSDESItem(ulSrcID, item); cbItems += item.length + 2; } /* * Increment item byte count for null termination */ cbItems++; // Align on word boundary // RTCP pkt length is in 32-bits word! cbItems += (cbItems % 4) ? 4 - (cbItems % 4) : 0; HX_ASSERT(cbItems % 4 == 0); // I am counting 32-bits word pktSDES.length = (cbItems / 4); // count of words - 1 //one more 32-bits for SSRC pktSDES.length++; return HXR_OK;}/* * Functions */HX_RESULTGetThresholdInfo(REF(ASMRuleBook) rules, float* pThreshold, REF(UINT32) ulNumThreshold){ HX_ASSERT(NULL != pThreshold); IHXValues* pValues = new CHXHeader(); IHXBuffer* pBuffer = new CHXBuffer(); pValues->AddRef(); pBuffer->AddRef(); // we have to send "Bandwidth" to be 0 in pValues UINT8 pBandwidth[128]; sprintf ((char *)pBandwidth, "%ld", 0); /* Flawfinder: ignore */ pBuffer->Set(pBandwidth, strlen((char *)pBandwidth) + 1); pValues->SetPropertyCString("Bandwidth", pBuffer); rules.GetPreEvaluate(pThreshold, ulNumThreshold, pValues, "Bandwidth"); pValues->Release(); pBuffer->Release(); return HXR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -