RTCP包时间间隔源码


  接着上一次的贴源代码,关于代码的原理请参见上一次的介绍。源码有非常清楚的注释,英文好一点的都能看懂。
  #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包占用的带宽。
   hs_uint32              members_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++; 
   }
   /* 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;     //这个用于判断我们目前是不是发送者
   /* 
   **  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;
   }   
 
   /* 
   ** 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 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);
   }
   /* 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 */
  恩,厚道的补充一下,这段代码的原始出处是guru prasad,经过改写而成。代码根据公司的平台改动较大,大家有兴趣的可以去找原始代码查看。代码的注释我没有写多少,因为英文注释基本上写的都很清楚了。可能有错漏的地方,下次在检查一遍。

你可能感兴趣的:(RTCP包时间间隔源码)