⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtcp_from_spec.c

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 C
字号:
/* RTCP code taken directly from the most recent RTP specification: *     draft-ietf-avt-rtp-new-11.txt * Implementation */#include "rtcp_from_spec.h"/*****A.7 Computing the RTCP Transmission Interval   The following functions implement the RTCP transmission and reception   rules described in Section 6.2. These rules are coded in several   functions:       o  rtcp_interval() computes the deterministic calculated          interval, measured in seconds.  The parameters are defined in          Section 6.3.       o  OnExpire() is called when the RTCP transmission timer expires.       o  OnReceive() is called whenever an RTCP packet is received.   Both OnExpire() and OnReceive() have event e as an argument. This is   the next scheduled event for that participant, either an RTCP report   or a BYE packet.  It is assumed that the following functions are   available:       o  Schedule(time t, event e) schedules an event e to occur at          time t. When time t arrives, the function OnExpire is called          with e as an argument.       o  Reschedule(time t, event e) reschedules a previously scheduled          event e for time t.       o  SendRTCPReport(event e) sends an RTCP report.       o  SendBYEPacket(event e) sends a BYE packet.       o  TypeOfEvent(event e) returns EVENT_BYE if the event being          processed is for a BYE packet to be sent, else it returns          EVENT_REPORT.       o  PacketType(p) returns PACKET_RTCP_REPORT if packet p is an          RTCP report (not BYE), PACKET_BYE if its a BYE RTCP packet,          and PACKET_RTP if its a regular RTP data packet.       o  ReceivedPacketSize() and SentPacketSize() return the size of          the referenced packet in octets.       o  NewMember(p) returns a 1 if the participant who sent packet p          is not currently in the member list, 0 otherwise. Note this          function is not sufficient for a complete implementation          because each CSRC identifier in an RTP packet and each SSRC in          a BYE packet should be processed.       o  NewSender(p) returns a 1 if the participant who sent packet p          is not currently in the sender sublist of the member list, 0          otherwise.       o  AddMember() and RemoveMember() to add and remove participants          from the member list.       o  AddSender() and RemoveSender() to add and remove participants          from the sender sublist of the member list.*****/   double rtcp_interval(int members,                        int senders,                        double rtcp_bw,                        int we_sent,                        double avg_rtcp_size,                        int initial)   {       /*        * Minimum average 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.;       /*        * 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);       /*        * To compensate for "unconditional reconsideration" converging to a        * value below the intended average.        */       double const COMPENSATION = 2.71828 - 1.5;       double t;                   /* interval */       double rtcp_min_time = RTCP_MIN_TIME;       int n;                      /* 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.        */       if (initial) {           rtcp_min_time /= 2;       }       /*        * If there were active senders, give them at least a minimum        * share of the RTCP bandwidth.  Otherwise all participants share        * the RTCP bandwidth equally.        */       n = members;       if (senders > 0 && senders < members * RTCP_SENDER_BW_FRACTION) {           if (we_sent) {               rtcp_bw *= RTCP_SENDER_BW_FRACTION;               n = senders;           } else {               rtcp_bw *= RTCP_RCVR_BW_FRACTION;               n -= senders;           }       }       /*        * 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 = 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.        */       t = t * (drand48() + 0.5);       t = t / COMPENSATION;       return t;   }   void OnExpire(event e,                 int    members,                 int    senders,                 double rtcp_bw,                 int    we_sent,                 double *avg_rtcp_size,                 int    *initial,                 time_tp   tc,                 time_tp   *tp,                 int    *pmembers)   {       /* This function is responsible for deciding whether to send        * an RTCP report or BYE packet now, or to reschedule transmission.        * It is also responsible for updating the pmembers, initial, tp,        * and avg_rtcp_size state variables. This function should be called        * upon expiration of the event timer used by Schedule(). */       double t;     /* Interval */       double tn;    /* Next transmit time */       /* In the case of a BYE, we use "unconditional reconsideration" to        * reschedule the transmission of the BYE if necessary */       if (TypeOfEvent(e) == EVENT_BYE) {           t = rtcp_interval(members,                             senders,                             rtcp_bw,                             we_sent,                             *avg_rtcp_size,                             *initial);           tn = *tp + t;           if (tn <= tc) {               SendBYEPacket(e);               exit(1);           } else {               Schedule(tn, e);           }       } else if (TypeOfEvent(e) == EVENT_REPORT) {           t = rtcp_interval(members,                             senders,                             rtcp_bw,                             we_sent,                             *avg_rtcp_size,                             *initial);           tn = *tp + t;           if (tn <= tc) {               SendRTCPReport(e);               *avg_rtcp_size = (1./16.)*SentPacketSize(e) +                   (15./16.)*(*avg_rtcp_size);               *tp = tc;               /* We must redraw the interval. Don't reuse the                  one computed above, since its not actually                  distributed the same, as we are conditioned                  on it being small enough to cause a packet to                  be sent */               t = rtcp_interval(members,                                 senders,                                 rtcp_bw,                                 we_sent,                                 *avg_rtcp_size,                                 *initial);               Schedule(t+tc,e);               *initial = 0;           } else {               Schedule(tn, e);           }           *pmembers = members;       }   }   void OnReceive(packet p,                  event e,                  int *members,                  int *pmembers,                  int *senders,                  double *avg_rtcp_size,                  double *tp,                  double tc,                  double tn)   {       /* What we do depends on whether we have left the group, and        * are waiting to send a BYE (TypeOfEvent(e) == EVENT_BYE) or        * an RTCP report. p represents the packet that was just received. */       if (PacketType(p) == PACKET_RTCP_REPORT) {           if (NewMember(p) && (TypeOfEvent(e) == EVENT_REPORT)) {               AddMember(p);               *members += 1;           }           *avg_rtcp_size = (1./16.)*ReceivedPacketSize(p) +               (15./16.)*(*avg_rtcp_size);       } else if (PacketType(p) == PACKET_RTP) {           if (NewMember(p) && (TypeOfEvent(e) == EVENT_REPORT)) {               AddMember(p);               *members += 1;           }           if (NewSender(p) && (TypeOfEvent(e) == EVENT_REPORT)) {               AddSender(p);               *senders += 1;           }       } else if (PacketType(p) == PACKET_BYE) {           *avg_rtcp_size = (1./16.)*ReceivedPacketSize(p) +               (15./16.)*(*avg_rtcp_size);           if (TypeOfEvent(e) == EVENT_REPORT) {               if (NewSender(p) == FALSE) {                   RemoveSender(p);                   *senders -= 1;               }               if (NewMember(p) == FALSE) {                   RemoveMember(p);                   *members -= 1;               }               if(*members < *pmembers) {                   tn = tc + (((double) *members)/(*pmembers))*(tn - tc);                   *tp = tc - (((double) *members)/(*pmembers))*(tc - *tp);                   /* Reschedule the next report for time tn */                   Reschedule(tn, e);                   *pmembers = *members;               }           } else if (TypeOfEvent(e) == EVENT_BYE) {               *members += 1;           }       }   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -