接着上一次的贴源代码,关于代码的原理请参见上一次的介绍。源码有非常清楚的注释,英文好一点的都能看懂。
#define RTCP_MIN_TIMEINTERVAL (5)
#define RTCP_SENDER_BW_FRACTION(x) ((x)/4)
#define RTCP_RCVR_BW_FRACTION(x) (3*(x)/4)
#define RTCP_NWKENCAP_UDPOVERIP (8+20) //8 UDP head 20 IP head
#define RTCP_SIZE_GAIN (1.0/16.0)
/*FUNCTION*---------------------------------------------------------------------
*
* Function Name : rtcp_compute_and_set_interval
* Description : Computes the time between transmission of RTCP packets
* and creates a one shot timer with calculate time interval.
* Returned Value : SUCCESS - on success
* FAILURE - on failure
*
*END*-------------------------------------------------------------------------*/
hs_int32
rtcp_compute_and_set_interval
(
rtp_node_t *rtp_node_p
)
{
long long ctmstmp_l; // ntp format (32.32 fixpt secs)
long long tinterval_l; // ntp format (32.32 fixpt secs)
long long rtcp_min_time_l = (RTCP_MIN_TIMEINTERVAL*1ULL) << 32; //1UUL 就是unsigned long long
int rtcp_bw_l = rtp_node_p->rtcp_bw; //这个是初始化时RTCP包占用的带宽。
*
* Function Name : rtcp_compute_and_set_interval
* Description : Computes the time between transmission of RTCP packets
* and creates a one shot timer with calculate time interval.
* Returned Value : SUCCESS - on success
* FAILURE - on failure
*
*END*-------------------------------------------------------------------------*/
hs_int32
rtcp_compute_and_set_interval
(
rtp_node_t *rtp_node_p
)
{
long long ctmstmp_l; // ntp format (32.32 fixpt secs)
long long tinterval_l; // ntp format (32.32 fixpt secs)
long long rtcp_min_time_l = (RTCP_MIN_TIMEINTERVAL*1ULL) << 32; //1UUL 就是unsigned long long
int rtcp_bw_l = rtp_node_p->rtcp_bw; //这个是初始化时RTCP包占用的带宽。
hs_uint32 members_l = 0;
hs_uint32 senders_l = 0;
hs_uint32 senders_l = 0;
/* Members for computation to share bandwidth*/
hs_uint32 no_of_members_l;
/* For the first packet */
if (rtp_node_p->avg_rtcp_size == 0)
{
rtcp_min_time_l /= 2;
/* 52 SR + 48 SDES CNAME + 8 UDP +20 IP */
rtp_node_p->avg_rtcp_size = 128;
}
/*
** While counting Members we are included.
** If RTP/RTCP packet received from otherside, then members are 2 otherwise 1
*/
members_l = 1;
if (rtp_node_p->rcvr_info.rcvr_ssrc != 0) //这个用于判断是否收到对方发送的RTP/RTCP包
{
members_l++;
}
hs_uint32 no_of_members_l;
/* For the first packet */
if (rtp_node_p->avg_rtcp_size == 0)
{
rtcp_min_time_l /= 2;
/* 52 SR + 48 SDES CNAME + 8 UDP +20 IP */
rtp_node_p->avg_rtcp_size = 128;
}
/*
** While counting Members we are included.
** If RTP/RTCP packet received from otherside, then members are 2 otherwise 1
*/
members_l = 1;
if (rtp_node_p->rcvr_info.rcvr_ssrc != 0) //这个用于判断是否收到对方发送的RTP/RTCP包
{
members_l++;
}
/* If we sent packet during this interval, we are included in senders */
senders_l = (rtp_node_p->sndr_info.send_flag == HS_TRUE) ? 1 : 0; //这个用于判断我们目前是不是发送者
senders_l = (rtp_node_p->sndr_info.send_flag == HS_TRUE) ? 1 : 0; //这个用于判断我们目前是不是发送者
/*
** If recently received RTCP packet is SR then increment
** number of senders
*/
if (rtp_node_p->rcvr_info.rmt_party == RTP_SENDER) //这个用来判断对方目前是否也是发送者
{
senders_l++;
}
no_of_members_l = members_l;
if ((senders_l > 0) && (senders_l < RTCP_SENDER_BW_FRACTION(members_l)))
{
if (rtp_node_p->sndr_info.send_flag == HS_TRUE)
{
rtcp_bw_l = RTCP_SENDER_BW_FRACTION(rtcp_bw_l);
no_of_members_l = senders_l;
}
else
{
rtcp_bw_l = RTCP_RCVR_BW_FRACTION(rtcp_bw_l);
no_of_members_l -= senders_l;
}
}/* End if ( (senders > 0) && (senders < members_l * RTCP_SENDER_BW_FRACTION)) */
** If recently received RTCP packet is SR then increment
** number of senders
*/
if (rtp_node_p->rcvr_info.rmt_party == RTP_SENDER) //这个用来判断对方目前是否也是发送者
{
senders_l++;
}
no_of_members_l = members_l;
if ((senders_l > 0) && (senders_l < RTCP_SENDER_BW_FRACTION(members_l)))
{
if (rtp_node_p->sndr_info.send_flag == HS_TRUE)
{
rtcp_bw_l = RTCP_SENDER_BW_FRACTION(rtcp_bw_l);
no_of_members_l = senders_l;
}
else
{
rtcp_bw_l = RTCP_RCVR_BW_FRACTION(rtcp_bw_l);
no_of_members_l -= senders_l;
}
}/* End if ( (senders > 0) && (senders < members_l * RTCP_SENDER_BW_FRACTION)) */
rtp_node_p->avg_rtcp_size +=
(rtp_node_p->sndr_info.rtcp_pkt_length + RTCP_NWKENCAP_UDPOVERIP -
rtp_node_p->avg_rtcp_size) * RTCP_SIZE_GAIN;
// ugh, we have to do an long int division but at least it is not floating pt
tinterval_l = (((rtp_node_p->avg_rtcp_size * no_of_members_l)*1ULL)<<32) / rtcp_bw_l;
if (tinterval_l < rtcp_min_time_l)
{
tinterval_l = rtcp_min_time_l;
}
(rtp_node_p->sndr_info.rtcp_pkt_length + RTCP_NWKENCAP_UDPOVERIP -
rtp_node_p->avg_rtcp_size) * RTCP_SIZE_GAIN;
// ugh, we have to do an long int division but at least it is not floating pt
tinterval_l = (((rtp_node_p->avg_rtcp_size * no_of_members_l)*1ULL)<<32) / rtcp_bw_l;
if (tinterval_l < rtcp_min_time_l)
{
tinterval_l = rtcp_min_time_l;
}
/*
** Get Random number, and normalizes it between 0.0 to 1.0.
** To avoid traffic bursts from unintended synchronization with other sites
** make the actual interval unifomly distributed between 0.5t and 1.5t
*/
// 32.32 fixed point (using long long and our
// randomlibGet() which returns 32 bit random number).
tinterval_l = tinterval_l/2 + (tinterval_l>>16) *
(randomlibGet()>>16);
** Get Random number, and normalizes it between 0.0 to 1.0.
** To avoid traffic bursts from unintended synchronization with other sites
** make the actual interval unifomly distributed between 0.5t and 1.5t
*/
// 32.32 fixed point (using long long and our
// randomlibGet() which returns 32 bit random number).
tinterval_l = tinterval_l/2 + (tinterval_l>>16) *
(randomlibGet()>>16);
/* At least one packet (RTP or RTCP) is received in previous RTCP interval */
if ((rtp_node_p->rcvr_info.time_elapsed == 0) &&
(rtp_node_p->rcvr_info.last_pkt_rcvd_time_flag != 0))
{
/* Compute the time difference between last packet received and to this time */
ctmstmp_l = NtpSinceBoot(); //此函数用于得到系统的绝对时间戳
/* Give the time difference in seconds */
rtp_node_p->rcvr_info.time_elapsed =
rtp_node_p->rcvr_info.last_pkt_rcvd_time - ctmstmp_l;
}
if ((rtp_node_p->rcvr_info.time_elapsed == 0) &&
(rtp_node_p->rcvr_info.last_pkt_rcvd_time_flag != 0))
{
/* Compute the time difference between last packet received and to this time */
ctmstmp_l = NtpSinceBoot(); //此函数用于得到系统的绝对时间戳
/* Give the time difference in seconds */
rtp_node_p->rcvr_info.time_elapsed =
rtp_node_p->rcvr_info.last_pkt_rcvd_time - ctmstmp_l;
}
/* If notification is more than the configured timeout */
if ((unsigned)((rtp_node_p->rcvr_info.time_elapsed + tinterval_l)>>32) >
(cm_get_rtp_timeout()/*seconds*/)) //此处用来判断超时
{
tinterval_l = (((long long)cm_get_rtp_timeout()<<32) -
rtp_node_p->rcvr_info.time_elapsed);
}
if ((unsigned)((rtp_node_p->rcvr_info.time_elapsed + tinterval_l)>>32) >
(cm_get_rtp_timeout()/*seconds*/)) //此处用来判断超时
{
tinterval_l = (((long long)cm_get_rtp_timeout()<<32) -
rtp_node_p->rcvr_info.time_elapsed);
}
/* Initial Timeout value. It should be in milli seconds */
TaskTimeoutRel( &rtp_node_p->v.timer_task,
ClockNtpToTicks(tinterval_l) ); //将发送RTCP包的任务放入任务队列,任务被激活的时间是tinterval_l
/* Increment the timeout value for RTO_TIMEOUT computation */
rtp_node_p->rcvr_info.time_elapsed += tinterval_l;
return(HS_SUCCESS);
}/* End rtcp_compute_set_interval */
TaskTimeoutRel( &rtp_node_p->v.timer_task,
ClockNtpToTicks(tinterval_l) ); //将发送RTCP包的任务放入任务队列,任务被激活的时间是tinterval_l
/* Increment the timeout value for RTO_TIMEOUT computation */
rtp_node_p->rcvr_info.time_elapsed += tinterval_l;
return(HS_SUCCESS);
}/* End rtcp_compute_set_interval */
恩,厚道的补充一下,这段代码的原始出处是guru prasad,经过改写而成。代码根据公司的平台改动较大,大家有兴趣的可以去找原始代码查看。代码的注释我没有写多少,因为英文注释基本上写的都很清楚了。可能有错漏的地方,下次在检查一遍。
浙公网安备 33010602011771号