diff -u /usr/src/asterisk-1.4.17/channels/chan_sip.c /usr/src/asterisk-1.4.17-audiortpqos/channels/chan_sip.c --- /usr/src/asterisk-1.4.17/channels/chan_sip.c 2008-03-12 14:56:28.000000000 -0400 +++ /usr/src/asterisk-1.4.17-audiortpqos/channels/chan_sip.c 2008-03-12 14:58:04.000000000 -0400 @@ -3571,9 +3571,47 @@ } else { /* Call is in UP state, send BYE */ if (!p->pendinginvite) { char *audioqos = ""; + char *audioqos_jitter = ""; + char *audioqos_loss = ""; + char *audioqos_rtt = ""; char *videoqos = ""; - if (p->rtp) + if (p->rtp) { audioqos = ast_rtp_get_quality(p->rtp, NULL); + audioqos_jitter = ast_rtp_get_quality_jitter(p->rtp, NULL); + audioqos_loss = ast_rtp_get_quality_loss(p->rtp, NULL); + audioqos_rtt = ast_rtp_get_quality_rtt(p->rtp, NULL); + if(oldowner) { + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOSJITTER", audioqos_jitter); + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOSLOSS", audioqos_loss); + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOSRTT", audioqos_rtt); + } + if(ast_bridged_channel(oldowner)) { + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOSBRIDGED", audioqos); + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOSJITTERBRIDGED", audioqos_jitter); + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOSLOSSBRIDGED", audioqos_loss); + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOSRTTBRIDGED", audioqos_rtt); + } + } + if (ast_bridged_channel(oldowner)) { + struct sip_pvt *q = ast_bridged_channel(oldowner)->tech_pvt; + if (q->rtp) { + audioqos = ast_rtp_get_quality(q->rtp, NULL); + audioqos_jitter = ast_rtp_get_quality_jitter(q->rtp, NULL); + audioqos_loss = ast_rtp_get_quality_loss(q->rtp, NULL); + audioqos_rtt = ast_rtp_get_quality_rtt(q->rtp, NULL); + } + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOS", audioqos); + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOSJITTER", audioqos_jitter); + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOSLOSS", audioqos_loss); + pbx_builtin_setvar_helper(ast_bridged_channel(oldowner), "RTPAUDIOQOSRTT", audioqos_rtt); + if (oldowner) { + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOSBRIDGED", audioqos); + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOSJITTERBRIDGED", audioqos_jitter); + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOSLOSSBRIDGED", audioqos_loss); + pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOSRTTBRIDGED", audioqos_rtt); + } + } if (p->vrtp) videoqos = ast_rtp_get_quality(p->vrtp, NULL); /* Send a hangup */ @@ -3582,12 +3620,15 @@ /* Get RTCP quality before end of call */ if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { if (p->rtp) + { append_history(p, "RTCPaudio", "Quality:%s", audioqos); + append_history(p, "RTCPaudioJitter", "Quality:%s", audioqos_jitter); + append_history(p, "RTCPaudioLoss", "Quality:%s", audioqos_loss); + append_history(p, "RTCPaudioRTT", "Quality:%s", audioqos_rtt); + } if (p->vrtp) append_history(p, "RTCPvideo", "Quality:%s", videoqos); } - if (p->rtp && oldowner) - pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); if (p->vrtp && oldowner) pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); } else { @@ -14659,13 +14700,49 @@ /* Get RTCP quality before end of call */ if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { - char *audioqos, *videoqos; + char *audioqos, *audioqos_jitter, *audioqos_loss, *audioqos_rtt, *videoqos; if (p->rtp) { audioqos = ast_rtp_get_quality(p->rtp, NULL); - if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) + audioqos_jitter = ast_rtp_get_quality_jitter(p->rtp, NULL); + audioqos_loss = ast_rtp_get_quality_loss(p->rtp, NULL); + audioqos_rtt = ast_rtp_get_quality_rtt(p->rtp, NULL); + if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { append_history(p, "RTCPaudio", "Quality:%s", audioqos); - if (p->owner) + append_history(p, "RTCPaudioJitter", "Quality:%s", audioqos_jitter); + append_history(p, "RTCPaudioLoss", "Quality:%s", audioqos_loss); + append_history(p, "RTCPaudioRTT", "Quality:%s", audioqos_rtt); + } + if (p->owner) { pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); + pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOSJITTER", audioqos_jitter); + pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOSLOSS", audioqos_loss); + pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOSRTT", audioqos_rtt); + } + if (ast_bridged_channel(p->owner)) { + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOSBRIDGED", audioqos); + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOSJITTERBRIDGED", audioqos_jitter); + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOSLOSSBRIDGED", audioqos_loss); + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOSRTTBRIDGED", audioqos_rtt); + } + } + if (ast_bridged_channel(p->owner)) { + struct sip_pvt *q = ast_bridged_channel(p->owner)->tech_pvt; + if (q->rtp) { + audioqos = ast_rtp_get_quality(q->rtp, NULL); + audioqos_jitter = ast_rtp_get_quality_jitter(q->rtp, NULL); + audioqos_loss = ast_rtp_get_quality_loss(q->rtp, NULL); + audioqos_rtt = ast_rtp_get_quality_rtt(q->rtp, NULL); + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOS", audioqos); + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOSJITTER", audioqos_jitter); + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOSLOSS", audioqos_loss); + pbx_builtin_setvar_helper(ast_bridged_channel(p->owner), "RTPAUDIOQOSRTT", audioqos_rtt); + if (p->owner) { + pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOSBRIDGED", audioqos); + pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOSJITTERBRIDGED", audioqos_jitter); + pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOSLOSSBRIDGED", audioqos_loss); + pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOSRTTBRIDGED", audioqos_rtt); + } + } } if (p->vrtp) { videoqos = ast_rtp_get_quality(p->vrtp, NULL); diff -u /usr/src/asterisk-1.4.17/main/rtp.c /usr/src/asterisk-1.4.17-audiortpqos/main/rtp.c --- /usr/src/asterisk-1.4.17/main/rtp.c 2008-03-12 14:57:06.000000000 -0400 +++ /usr/src/asterisk-1.4.17-audiortpqos/main/rtp.c 2008-03-12 14:58:26.000000000 -0400 @@ -42,6 +42,7 @@ #include #include #include +#include #include "asterisk/rtp.h" #include "asterisk/frame.h" @@ -205,6 +206,7 @@ * */ struct ast_rtcp { + int rtcp_info; int s; /*!< Socket */ struct sockaddr_in us; /*!< Socket representation of the local endpoint. */ struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */ @@ -224,10 +226,38 @@ unsigned int reported_jitter; /*!< The contents of their last jitter entry in the RR */ unsigned int reported_lost; /*!< Reported lost packets in their RR */ char quality[AST_MAX_USER_FIELD]; + char quality_jitter[AST_MAX_USER_FIELD]; + char quality_loss[AST_MAX_USER_FIELD]; + char quality_rtt[AST_MAX_USER_FIELD]; + + double reported_maxjitter; + double reported_minjitter; + double reported_normdev_jitter; + double reported_stdev_jitter; + unsigned int reported_jitter_count; + + double reported_maxlost; + double reported_minlost; + double reported_normdev_lost; + double reported_stdev_lost; + + double rxlost; + double maxrxlost; + double minrxlost; + double normdev_rxlost; + double stdev_rxlost; + unsigned int rxlost_count; + double maxrxjitter; double minrxjitter; + double normdev_rxjitter; + double stdev_rxjitter; + unsigned int rxjitter_count; double maxrtt; double minrtt; + double normdevrtt; + double stdevrtt; + unsigned int rtt_count; int sendfur; }; @@ -844,6 +874,12 @@ unsigned int comp; struct ast_frame *f = &ast_null_frame; + double reported_jitter; + double reported_normdev_jitter_current; + double normdevrtt_current; + double reported_lost; + double reported_normdev_lost_current; + if (!rtp || !rtp->rtcp) return &ast_null_frame; @@ -938,14 +974,20 @@ } rtt = rtt / 1000.; rttsec = rtt / 1000.; + rtp->rtcp->rtt = rttsec; if (comp - dlsr >= lsr) { rtp->rtcp->accumulated_transit += rttsec; - rtp->rtcp->rtt = rttsec; + if (rtp->rtcp->rtt_count == 0) + rtp->rtcp->minrtt = rttsec; if (rtp->rtcp->maxrttrtcp->maxrtt = rttsec; if (rtp->rtcp->minrtt>rttsec) rtp->rtcp->minrtt = rttsec; + normdevrtt_current = normdev_compute(rtp->rtcp->normdevrtt, rttsec, rtp->rtcp->rtt_count); + rtp->rtcp->stdevrtt = stddev_compute(rtp->rtcp->stdevrtt, rttsec, rtp->rtcp->normdevrtt, normdevrtt_current, rtp->rtcp->rtt_count); + rtp->rtcp->normdevrtt = normdevrtt_current; + rtp->rtcp->rtt_count++; } else if (rtcp_debug_test_addr(&sin)) { ast_verbose("Internal RTCP NTP clock skew detected: " "lsr=%u, now=%u, dlsr=%u (%d:%03dms), " @@ -957,7 +999,31 @@ } rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]); + reported_jitter = (double) rtp->rtcp->reported_jitter; + if (rtp->rtcp->reported_jitter_count == 0) + rtp->rtcp->reported_minjitter = reported_jitter; + if (reported_jitter < rtp->rtcp->reported_minjitter) + rtp->rtcp->reported_minjitter = reported_jitter; + if (reported_jitter > rtp->rtcp->reported_maxjitter) + rtp->rtcp->reported_maxjitter = reported_jitter; + reported_normdev_jitter_current = normdev_compute(rtp->rtcp->reported_normdev_jitter, reported_jitter, rtp->rtcp->reported_jitter_count); + rtp->rtcp->reported_stdev_jitter = stddev_compute(rtp->rtcp->reported_stdev_jitter, reported_jitter, rtp->rtcp->reported_normdev_jitter, reported_normdev_jitter_current, rtp->rtcp->reported_jitter_count); + rtp->rtcp->reported_normdev_jitter = reported_normdev_jitter_current; + rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff; + reported_lost = (double) rtp->rtcp->reported_lost; + //using same counter as for jitter + if(rtp->rtcp->reported_jitter_count == 0) + rtp->rtcp->reported_minlost = reported_lost; + if(reported_lost < rtp->rtcp->reported_minlost) + rtp->rtcp->reported_minlost = reported_lost; + if(reported_lost > rtp->rtcp->reported_maxlost) + rtp->rtcp->reported_maxlost = reported_lost; + reported_normdev_lost_current = normdev_compute(rtp->rtcp->reported_normdev_lost, reported_lost, rtp->rtcp->reported_jitter_count); + rtp->rtcp->reported_stdev_lost = stddev_compute(rtp->rtcp->reported_stdev_lost, reported_lost, rtp->rtcp->reported_normdev_lost, reported_normdev_lost_current, rtp->rtcp->reported_jitter_count); + rtp->rtcp->reported_normdev_lost = reported_normdev_lost_current; + rtp->rtcp->reported_jitter_count++; + if (rtcp_debug_test_addr(&sin)) { ast_verbose(" Fraction lost: %ld\n", (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24)); ast_verbose(" Packets lost so far: %d\n", rtp->rtcp->reported_lost); @@ -996,7 +1062,7 @@ } position += (length + 1); } - + rtp->rtcp->rtcp_info = 1; return f; } @@ -1008,7 +1074,7 @@ double d; double dtv; double prog; - + double normdev_rxjitter_current; if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) { gettimeofday(&rtp->rxcore, NULL); rtp->drxcore = (double) rtp->rxcore.tv_sec + (double) rtp->rxcore.tv_usec / 1000000; @@ -1044,8 +1110,31 @@ rtp->rxjitter += (1./16.) * (d - rtp->rxjitter); if (rtp->rtcp && rtp->rxjitter > rtp->rtcp->maxrxjitter) rtp->rtcp->maxrxjitter = rtp->rxjitter; + if (rtp->rtcp->rxjitter_count == 1) + rtp->rtcp->minrxjitter = rtp->rxjitter; if (rtp->rtcp && rtp->rxjitter < rtp->rtcp->minrxjitter) rtp->rtcp->minrxjitter = rtp->rxjitter; + + normdev_rxjitter_current = normdev_compute(rtp->rtcp->normdev_rxjitter,rtp->rxjitter,rtp->rtcp->rxjitter_count); + rtp->rtcp->stdev_rxjitter = stddev_compute(rtp->rtcp->stdev_rxjitter,rtp->rxjitter,rtp->rtcp->normdev_rxjitter,normdev_rxjitter_current,rtp->rtcp->rxjitter_count); + + rtp->rtcp->normdev_rxjitter = normdev_rxjitter_current; + rtp->rtcp->rxjitter_count++; +} + +/*! \brief Calculate normal deviation */ +double normdev_compute(double normdev,double sample,unsigned int sample_count) +{ + return (normdev*sample_count+sample)/(sample_count+1); +} + +double stddev_compute(double stddev,double sample,double normdev,double normdev_curent,unsigned int sample_count) +{ + //for the formula check http://www.cs.umd.edu/~austinjp/constSD.pdf + //return sqrt( (sample_count*pow(stddev,2) + sample_count*pow((sample-normdev)/(sample_count+1),2) + pow(sample-normdev_curent,2)) / (sample_count+1)); + //we can compute the sigma^2 and that way we would have to do the sqrt only 1 time at the end and would save another pow 2 compute + //optimized formula + return (sample_count*stddev + sample_count*pow((sample - normdev) / (sample_count + 1), 2) + pow(sample-normdev_curent, 2)) / (sample_count + 1); } /*! \brief Perform a Packet2Packet RTP write */ @@ -1115,7 +1204,7 @@ unsigned int timestamp; unsigned int *rtpheader; struct rtpPayloadType rtpPT; - struct ast_rtp *bridged = NULL; + /* struct ast_rtp *bridged = NULL; */ /* If time is up, kill it */ if (rtp->sending_digit) @@ -1179,8 +1268,8 @@ } /* If we are bridged to another RTP stream, send direct */ - if ((bridged = ast_rtp_get_bridged(rtp)) && !bridge_p2p_rtp_write(rtp, bridged, rtpheader, res, hdrlen)) - return &ast_null_frame; + /* if ((bridged = ast_rtp_get_bridged(rtp)) && !bridge_p2p_rtp_write(rtp, bridged, rtpheader, res, hdrlen)) + return &ast_null_frame; */ if (version != 2) return &ast_null_frame; @@ -2065,6 +2154,75 @@ rtp->rxseqno = 0; } + + +char *ast_rtp_get_quality_jitter(struct ast_rtp *rtp, struct ast_rtp_quality *qual) +{ + /* + *ssrc our ssrc + *themssrc their ssrc + *lp lost packets + *rxjitter our calculated jitter(rx) + *rxcount no. received packets + *txjitter reported jitter of the other end + *txcount transmitted packets + *rlp remote lost packets + *rtt round trip time + */ + + if((rtp->rtcp)&&(rtp->rtcp->rtcp_info)) { + snprintf(rtp->rtcp->quality_jitter, sizeof(rtp->rtcp->quality_jitter), "minrxjitter=%f;maxrxjitter=%f;avgrxjitter=%f;stdevrxjitter=%f;reported_minjitter=%f;reported_maxjitter=%f;reported_avgjitter=%f;reported_stdevjitter=%f;", + rtp->rtcp->minrxjitter,rtp->rtcp->maxrxjitter,rtp->rtcp->normdev_rxjitter,sqrt(rtp->rtcp->stdev_rxjitter), + rtp->rtcp->reported_minjitter,rtp->rtcp->reported_maxjitter,rtp->rtcp->reported_normdev_jitter,sqrt(rtp->rtcp->reported_stdev_jitter) + ); + } + else + snprintf(rtp->rtcp->quality_jitter, sizeof(rtp->rtcp->quality_jitter),"rxjitter=%f;",rtp->rxjitter); + return rtp->rtcp->quality_jitter; +} + +char *ast_rtp_get_quality_loss(struct ast_rtp *rtp, struct ast_rtp_quality *qual) +{ + unsigned int lost; + unsigned int extended; + unsigned int expected; + int fraction; + + if((rtp->rtcp)&&(rtp->rtcp->rtcp_info)&&(rtp->rtcp->maxrxlost!=0)) { + snprintf(rtp->rtcp->quality_loss, sizeof(rtp->rtcp->quality_loss), "minrxlost=%f;maxrxlost=%f;avgrxlostr=%f;stdevrxlost=%f;reported_minlost=%f;reported_maxlost=%f;reported_avglost=%f;reported_stdevlost=%f;", + rtp->rtcp->minrxlost,rtp->rtcp->maxrxlost,rtp->rtcp->normdev_rxlost,sqrt(rtp->rtcp->stdev_rxlost), + rtp->rtcp->reported_minlost,rtp->rtcp->reported_maxlost,rtp->rtcp->reported_normdev_lost,sqrt(rtp->rtcp->reported_stdev_lost) + ); + } + else { + extended = rtp->cycles + rtp->lastrxseqno; + expected = extended - rtp->seedrxseqno + 1; + if (rtp->rxcount > expected) + expected += rtp->rxcount - expected; + lost = expected - rtp->rxcount; + + if ((expected == 0) || (lost <= 0)) + fraction = 0; + else + fraction = (lost<<8) / expected ; + + snprintf(rtp->rtcp->quality_loss, sizeof(rtp->rtcp->quality_loss), "lost=%d;expected=%d;",lost,expected); + } + return rtp->rtcp->quality_loss; +} + +char *ast_rtp_get_quality_rtt(struct ast_rtp *rtp, struct ast_rtp_quality *qual) +{ + if((rtp->rtcp)&&(rtp->rtcp->rtcp_info)) { + snprintf(rtp->rtcp->quality_rtt, sizeof(rtp->rtcp->quality_rtt), "minrtt=%f;maxrtt=%f;avgrtt=%f;stdevrtt=%f;", + rtp->rtcp->minrtt,rtp->rtcp->maxrtt,rtp->rtcp->normdevrtt,sqrt(rtp->rtcp->stdevrtt) + ); + } + else + snprintf(rtp->rtcp->quality_rtt, sizeof(rtp->rtcp->quality_rtt), "Not available"); + return rtp->rtcp->quality_rtt; +} + char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual) { /* @@ -2092,7 +2250,7 @@ qual->rtt = rtp->rtcp->rtt; } } - if (rtp->rtcp) { + if ((rtp->rtcp)&&(rtp->rtcp->rtcp_info)) { snprintf(rtp->rtcp->quality, sizeof(rtp->rtcp->quality), "ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f", rtp->ssrc, @@ -2104,9 +2262,16 @@ rtp->txcount, rtp->rtcp->reported_lost, rtp->rtcp->rtt); - return rtp->rtcp->quality; - } else - return " - RTP/RTCP has already been destroyed"; + } + else { + snprintf(rtp->rtcp->quality, sizeof(rtp->rtcp->quality), "ssrc=%u;themssrc=%u;rxjitter=%f;rxcount=%u;txcount=%u;", + rtp->ssrc, + rtp->themssrc, + rtp->rxjitter, + rtp->rxcount, + rtp->txcount); + } + return rtp->rtcp->quality; } void ast_rtp_destroy(struct ast_rtp *rtp) @@ -2357,6 +2522,7 @@ int fraction; struct timeval dlsr; char bdata[512]; + /*double rxlost_current;*/ /* Commented condition is always not NULL if rtp->rtcp is not NULL */ if (!rtp || !rtp->rtcp/* || (&rtp->rtcp->them.sin_addr == 0)*/) @@ -2470,6 +2636,8 @@ struct timeval dlsr; int fraction; + double rxlost_current; + if (!rtp || !rtp->rtcp || (&rtp->rtcp->them.sin_addr == 0)) return 0; @@ -2489,6 +2657,22 @@ received_interval = rtp->rxcount - rtp->rtcp->received_prior; rtp->rtcp->received_prior = rtp->rxcount; lost_interval = expected_interval - received_interval; + + if (lost_interval <= 0) + rtp->rtcp->rxlost = 0; + else rtp->rtcp->rxlost = rtp->rtcp->rxlost; + if (rtp->rtcp->rxlost_count == 0) + rtp->rtcp->minrxlost = rtp->rtcp->rxlost; + if (lost_interval < rtp->rtcp->minrxlost) + rtp->rtcp->minrxlost = rtp->rtcp->rxlost; + if (lost_interval > rtp->rtcp->maxrxlost) + rtp->rtcp->maxrxlost = rtp->rtcp->rxlost; + + rxlost_current = normdev_compute(rtp->rtcp->normdev_rxlost, rtp->rtcp->rxlost, rtp->rtcp->rxlost_count); + rtp->rtcp->stdev_rxlost = stddev_compute(rtp->rtcp->stdev_rxlost, rtp->rtcp->rxlost, rtp->rtcp->normdev_rxlost, rxlost_current, rtp->rtcp->rxlost_count); + rtp->rtcp->normdev_rxlost = rxlost_current; + rtp->rtcp->rxlost_count++; + if (expected_interval == 0 || lost_interval <= 0) fraction = 0; else diff -u /usr/src/asterisk-1.4.17/include/asterisk/rtp.h /usr/src/asterisk-1.4.17-audiortpqos/include/asterisk/rtp.h --- /usr/src/asterisk-1.4.17/include/asterisk/rtp.h 2008-03-12 14:57:33.000000000 -0400 +++ /usr/src/asterisk-1.4.17-audiortpqos/include/asterisk/rtp.h 2008-03-12 14:58:11.000000000 -0400 @@ -225,7 +225,10 @@ /*! \brief Return RTCP quality string */ char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual); - +/*! \Verbose Return RTCP quality string */ +char *ast_rtp_get_quality_jitter(struct ast_rtp *rtp, struct ast_rtp_quality *qual); +char *ast_rtp_get_quality_loss(struct ast_rtp *rtp, struct ast_rtp_quality *qual); +char *ast_rtp_get_quality_rtt(struct ast_rtp *rtp, struct ast_rtp_quality *qual); /*! \brief Send an H.261 fast update request. Some devices need this rather than the XML message in SIP */ int ast_rtcp_send_h261fur(void *data); @@ -256,6 +259,9 @@ /* \brief Put RTP timeout timers on hold during another transaction, like T.38 */ void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp); + +double normdev_compute(double normdev,double sample,unsigned int sample_count); +double stddev_compute(double stddev,double sample,double normdev,double normdev_curent,unsigned int sample_count); #if defined(__cplusplus) || defined(c_plusplus) } #endif