@ -33,8 +33,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
# include <sys/time.h>
# include <signal.h>
# include <fcntl.h>
# include <math.h>
# include "asterisk/rtp.h"
# include "asterisk/pbx.h"
# include "asterisk/frame.h"
# include "asterisk/channel.h"
# include "asterisk/acl.h"
@ -229,6 +231,7 @@ int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
*
*/
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. */
@ -248,10 +251,38 @@ struct ast_rtcp {
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 ;
} ;
@ -805,6 +836,35 @@ static void rtp_bridge_unlock(struct ast_rtp *rtp)
return ;
}
/*! \brief Calculate normal deviation */
static double normdev_compute ( double normdev , double sample , unsigned int sample_count )
{
normdev = normdev * sample_count + sample ;
sample_count + + ;
return normdev / sample_count ;
}
static 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
*/
# define SQUARE(x) ((x) * (x))
stddev = sample_count * stddev ;
sample_count + + ;
return stddev +
( sample_count * SQUARE ( ( sample - normdev ) / sample_count ) ) +
( SQUARE ( sample - normdev_curent ) / sample_count ) ;
# undef SQUARE
}
static struct ast_frame * send_dtmf ( struct ast_rtp * rtp , enum ast_frame_type type )
{
if ( ( ( ast_test_flag ( rtp , FLAG_DTMF_COMPENSATE ) & & type = = AST_FRAME_DTMF_END ) | |
@ -1086,6 +1146,12 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
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 ;
@ -1179,14 +1245,27 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
}
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 - > maxrtt < rttsec )
rtp - > rtcp - > 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), "
@ -1198,7 +1277,45 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
}
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 ) ;
@ -1210,6 +1327,7 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
if ( rtt )
ast_verbose ( " RTT: %lu(sec) \n " , ( unsigned long ) rtt ) ;
}
if ( rtt ) {
manager_event ( EVENT_FLAG_REPORTING , " RTCPReceived " , " From %s:%d \r \n "
" PT: %d(%s) \r \n "
@ -1286,7 +1404,7 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
}
position + = ( length + 1 ) ;
}
rtp - > rtcp - > rtcp_info = 1 ;
return f ;
}
@ -1299,6 +1417,7 @@ static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int t
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 ;
@ -1334,8 +1453,16 @@ static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int t
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 Perform a Packet2Packet RTP write */
@ -1557,7 +1684,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
/* Schedule transmission of Receiver Report */
rtp - > rtcp - > schedid = ast_sched_add ( rtp - > sched , ast_rtcp_calc_interval ( rtp ) , ast_rtcp_write , rtp ) ;
}
if ( ( int ) rtp - > lastrxseqno - ( int ) seqno > 100 ) /* if so it would indicate that the sender cycled; allow for misordering */
if ( ( int ) rtp - > lastrxseqno - ( int ) seqno > 100 ) /* if so it would indicate that the sender cycled; allow for misordering */
rtp - > cycles + = RTP_SEQ_MOD ;
prev_seqno = rtp - > lastrxseqno ;
@ -1688,7 +1815,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
ast_set_flag ( & rtp - > f , AST_FRFLAG_HAS_TIMING_INFO ) ;
rtp - > f . ts = timestamp / 8 ;
rtp - > f . len = rtp - > f . samples / ( ( ast_format_rate ( rtp - > f . subclass ) = = 16000 ) ? 16 : 8 ) ;
} else if ( rtp - > f . subclass & AST_FORMAT_VIDEO_MASK ) {
} else if ( rtp - > f . subclass & AST_FORMAT_VIDEO_MASK ) {
/* Video -- samples is # of samples vs. 90000 */
if ( ! rtp - > lastividtimestamp )
rtp - > lastividtimestamp = timestamp ;
@ -2497,7 +2624,89 @@ void ast_rtp_reset(struct ast_rtp *rtp)
rtp - > rxseqno = 0 ;
}
char * ast_rtp_get_quality ( struct ast_rtp * rtp , struct ast_rtp_quality * qual )
static double __ast_rtp_get_qos ( struct ast_rtp * rtp , const char * qos , int * found )
{
* found = 1 ;
if ( ! strcasecmp ( qos , " remote_maxjitter " ) )
return rtp - > rtcp - > reported_maxjitter * 1000.0 ;
if ( ! strcasecmp ( qos , " remote_minjitter " ) )
return rtp - > rtcp - > reported_minjitter * 1000.0 ;
if ( ! strcasecmp ( qos , " remote_normdevjitter " ) )
return rtp - > rtcp - > reported_normdev_jitter * 1000.0 ;
if ( ! strcasecmp ( qos , " remote_stdevjitter " ) )
return sqrt ( rtp - > rtcp - > reported_stdev_jitter ) * 1000.0 ;
if ( ! strcasecmp ( qos , " local_maxjitter " ) )
return rtp - > rtcp - > maxrxjitter * 1000.0 ;
if ( ! strcasecmp ( qos , " local_minjitter " ) )
return rtp - > rtcp - > minrxjitter * 1000.0 ;
if ( ! strcasecmp ( qos , " local_normdevjitter " ) )
return rtp - > rtcp - > normdev_rxjitter * 1000.0 ;
if ( ! strcasecmp ( qos , " local_stdevjitter " ) )
return sqrt ( rtp - > rtcp - > stdev_rxjitter ) * 1000.0 ;
if ( ! strcasecmp ( qos , " maxrtt " ) )
return rtp - > rtcp - > maxrtt * 1000.0 ;
if ( ! strcasecmp ( qos , " minrtt " ) )
return rtp - > rtcp - > minrtt * 1000.0 ;
if ( ! strcasecmp ( qos , " normdevrtt " ) )
return rtp - > rtcp - > normdevrtt * 1000.0 ;
if ( ! strcasecmp ( qos , " stdevrtt " ) )
return sqrt ( rtp - > rtcp - > stdevrtt ) * 1000.0 ;
* found = 0 ;
return 0.0 ;
}
int ast_rtp_get_qos ( struct ast_rtp * rtp , const char * qos , char * buf , unsigned int buflen )
{
double value ;
int found ;
value = __ast_rtp_get_qos ( rtp , qos , & found ) ;
if ( ! found )
return - 1 ;
snprintf ( buf , buflen , " %.0lf " , value ) ;
return 0 ;
}
void ast_rtp_set_vars ( struct ast_channel * chan , struct ast_rtp * rtp ) {
char * audioqos ;
char * audioqos_jitter ;
char * audioqos_loss ;
char * audioqos_rtt ;
struct ast_channel * bridge ;
if ( ! rtp | | ! chan )
return ;
bridge = ast_bridged_channel ( chan ) ;
audioqos = ast_rtp_get_quality ( rtp , NULL , RTPQOS_SUMMARY ) ;
audioqos_jitter = ast_rtp_get_quality ( rtp , NULL , RTPQOS_JITTER ) ;
audioqos_loss = ast_rtp_get_quality ( rtp , NULL , RTPQOS_LOSS ) ;
audioqos_rtt = ast_rtp_get_quality ( rtp , NULL , RTPQOS_RTT ) ;
pbx_builtin_setvar_helper ( chan , " RTPAUDIOQOS " , audioqos ) ;
pbx_builtin_setvar_helper ( chan , " RTPAUDIOQOSJITTER " , audioqos_jitter ) ;
pbx_builtin_setvar_helper ( chan , " RTPAUDIOQOSLOSS " , audioqos_loss ) ;
pbx_builtin_setvar_helper ( chan , " RTPAUDIOQOSRTT " , audioqos_rtt ) ;
if ( ! bridge )
return ;
pbx_builtin_setvar_helper ( bridge , " RTPAUDIOQOSBRIDGED " , audioqos ) ;
pbx_builtin_setvar_helper ( bridge , " RTPAUDIOQOSJITTERBRIDGED " , audioqos_jitter ) ;
pbx_builtin_setvar_helper ( bridge , " RTPAUDIOQOSLOSSBRIDGED " , audioqos_loss ) ;
pbx_builtin_setvar_helper ( bridge , " RTPAUDIOQOSRTTBRIDGED " , audioqos_rtt ) ;
}
static char * __ast_rtp_get_quality_jitter ( struct ast_rtp * rtp )
{
/*
* ssrc our ssrc
@ -2510,21 +2719,129 @@ char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual)
* rlp remote lost packets
* rtt round trip time
*/
# define RTCP_JITTER_FORMAT1 \
" minrxjitter=%f; " \
" maxrxjitter=%f; " \
" avgrxjitter=%f; " \
" stdevrxjitter=%f; " \
" reported_minjitter=%f; " \
" reported_maxjitter=%f; " \
" reported_avgjitter=%f; " \
" reported_stdevjitter=%f; "
# define RTCP_JITTER_FORMAT2 \
" rxjitter=%f; "
if ( rtp - > rtcp & & rtp - > rtcp - > rtcp_info ) {
snprintf ( rtp - > rtcp - > quality_jitter , sizeof ( rtp - > rtcp - > quality_jitter ) , RTCP_JITTER_FORMAT1 ,
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 ) , RTCP_JITTER_FORMAT2 ,
rtp - > rxjitter
) ;
}
if ( qual & & rtp ) {
qual - > local_ssrc = rtp - > ssrc ;
qual - > local_jitter = rtp - > rxjitter ;
qual - > local_count = rtp - > rxcount ;
qual - > remote_ssrc = rtp - > themssrc ;
qual - > remote_count = rtp - > txcount ;
if ( rtp - > rtcp ) {
qual - > local_lostpackets = rtp - > rtcp - > expected_prior - rtp - > rtcp - > received_prior ;
qual - > remote_lostpackets = rtp - > rtcp - > reported_lost ;
qual - > remote_jitter = rtp - > rtcp - > reported_jitter / 65536.0 ;
qual - > rtt = rtp - > rtcp - > rtt ;
}
return rtp - > rtcp - > quality_jitter ;
# undef RTCP_JITTER_FORMAT1
# undef RTCP_JITTER_FORMAT2
}
static char * __ast_rtp_get_quality_loss ( struct ast_rtp * rtp )
{
unsigned int lost ;
unsigned int extended ;
unsigned int expected ;
int fraction ;
# define RTCP_LOSS_FORMAT1 \
" minrxlost=%f; " \
" maxrxlost=%f; " \
" avgrxlostr=%f; " \
" stdevrxlost=%f; " \
" reported_minlost=%f; " \
" reported_maxlost=%f; " \
" reported_avglost=%f; " \
" reported_stdevlost=%f; "
# define RTCP_LOSS_FORMAT2 \
" lost=%d; " \
" expected=%d; "
if ( rtp - > rtcp & & rtp - > rtcp - > rtcp_info & & rtp - > rtcp - > maxrxlost > 0 ) {
snprintf ( rtp - > rtcp - > quality_loss , sizeof ( rtp - > rtcp - > quality_loss ) , RTCP_LOSS_FORMAT1 ,
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 | | lost < = 0 )
fraction = 0 ;
else
fraction = ( lost < < 8 ) / expected ;
snprintf ( rtp - > rtcp - > quality_loss , sizeof ( rtp - > rtcp - > quality_loss ) , RTCP_LOSS_FORMAT2 ,
lost ,
expected
) ;
}
if ( rtp - > rtcp ) {
return rtp - > rtcp - > quality_loss ;
# undef RTCP_LOSS_FORMAT1
# undef RTCP_LOSS_FORMAT2
}
static char * __ast_rtp_get_quality_rtt ( struct ast_rtp * rtp )
{
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 ;
}
static char * __ast_rtp_get_quality ( struct ast_rtp * rtp )
{
/*
* 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 , sizeof ( rtp - > rtcp - > quality ) ,
" ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f " ,
rtp - > ssrc ,
@ -2535,10 +2852,50 @@ char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual)
( double ) rtp - > rtcp - > reported_jitter / 65536.0 ,
rtp - > txcount ,
rtp - > rtcp - > reported_lost ,
rtp - > rtcp - > rtt ) ;
return rtp - > rtcp - > quality ;
} else
return " <Unknown> - RTP/RTCP has already been destroyed " ;
rtp - > rtcp - > rtt
) ;
} 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 ;
}
char * ast_rtp_get_quality ( struct ast_rtp * rtp , struct ast_rtp_quality * qual , enum ast_rtp_quality_type qtype )
{
if ( qual & & rtp ) {
qual - > local_ssrc = rtp - > ssrc ;
qual - > local_jitter = rtp - > rxjitter ;
qual - > local_count = rtp - > rxcount ;
qual - > remote_ssrc = rtp - > themssrc ;
qual - > remote_count = rtp - > txcount ;
if ( rtp - > rtcp ) {
qual - > local_lostpackets = rtp - > rtcp - > expected_prior - rtp - > rtcp - > received_prior ;
qual - > remote_lostpackets = rtp - > rtcp - > reported_lost ;
qual - > remote_jitter = rtp - > rtcp - > reported_jitter / 65536.0 ;
qual - > rtt = rtp - > rtcp - > rtt ;
}
}
switch ( qtype ) {
case RTPQOS_SUMMARY :
return __ast_rtp_get_quality ( rtp ) ;
case RTPQOS_JITTER :
return __ast_rtp_get_quality_jitter ( rtp ) ;
case RTPQOS_LOSS :
return __ast_rtp_get_quality_loss ( rtp ) ;
case RTPQOS_RTT :
return __ast_rtp_get_quality_rtt ( rtp ) ;
}
return NULL ;
}
void ast_rtp_destroy ( struct ast_rtp * rtp )
@ -2944,6 +3301,8 @@ static int ast_rtcp_write_rr(const void *data)
struct timeval dlsr ;
int fraction ;
double rxlost_current ;
if ( ! rtp | | ! rtp - > rtcp | | ( & rtp - > rtcp - > them . sin_addr = = 0 ) )
return 0 ;
@ -2961,6 +3320,22 @@ static int ast_rtcp_write_rr(const void *data)
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
@ -3223,7 +3598,7 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
return 0 ;
/* If there is no data length, return immediately */
if ( ! _f - > datalen & & ! rtp - > red )
if ( ! _f - > datalen & & ! rtp - > red )
return 0 ;
/* Make sure we have enough space for RTP header */
@ -3903,8 +4278,8 @@ enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel
* we can still do packet - to - packet bridging , because passing through the
* core will handle DTMF mode translation .
*/
if ( ( ast_test_flag ( p0 , FLAG_HAS_DTMF ) ! = ast_test_flag ( p1 , FLAG_HAS_DTMF ) ) | |
( ! c0 - > tech - > send_digit_begin ! = ! c1 - > tech - > send_digit_begin ) ) {
if ( ( ast_test_flag ( p0 , FLAG_HAS_DTMF ) ! = ast_test_flag ( p1 , FLAG_HAS_DTMF ) ) | |
( ! c0 - > tech - > send_digit_begin ! = ! c1 - > tech - > send_digit_begin ) ) {
if ( ! ast_test_flag ( p0 , FLAG_P2P_NEED_DTMF ) | | ! ast_test_flag ( p1 , FLAG_P2P_NEED_DTMF ) ) {
ast_channel_unlock ( c0 ) ;
ast_channel_unlock ( c1 ) ;
@ -4456,7 +4831,7 @@ int rtp_red_init(struct ast_rtp *rtp, int ti, int *red_data_pt, int num_gen)
*/
void red_buffer_t140 ( struct ast_rtp * rtp , struct ast_frame * f )
{
if ( f - > datalen > - 1 ) {
if ( f - > datalen > - 1 ) {
struct rtp_red * red = rtp - > red ;
memcpy ( & red - > buf_data [ red - > t140 . datalen ] , f - > data . ptr , f - > datalen ) ;
red - > t140 . datalen + = f - > datalen ;