Commit 078fe3b1 authored by Ghislain MARY's avatar Ghislain MARY

Fill RTCP XR voip-metrics packets.

parent 062c592e
...@@ -114,6 +114,8 @@ typedef struct _OrtpNetworkSimulatorCtx{ ...@@ -114,6 +114,8 @@ typedef struct _OrtpNetworkSimulatorCtx{
struct timeval last_check; struct timeval last_check;
}OrtpNetworkSimulatorCtx; }OrtpNetworkSimulatorCtx;
#define ORTP_RTCP_XR_UNAVAILABLE_PARAMETER 127
typedef enum { typedef enum {
OrtpRtcpXrRcvrRttNone, OrtpRtcpXrRcvrRttNone,
OrtpRtcpXrRcvrRttAll, OrtpRtcpXrRcvrRttAll,
...@@ -156,6 +158,10 @@ typedef struct OrtpRtcpXrStats { ...@@ -156,6 +158,10 @@ typedef struct OrtpRtcpXrStats {
double newm_ttl_or_hl_since_last_stat_summary; double newm_ttl_or_hl_since_last_stat_summary;
uint8_t min_ttl_or_hl_since_last_stat_summary; /* The minimum value of TTL/HL since last XR stat-summary was sent */ uint8_t min_ttl_or_hl_since_last_stat_summary; /* The minimum value of TTL/HL since last XR stat-summary was sent */
uint8_t max_ttl_or_hl_since_last_stat_summary; /* The maximum value of TTL/HL since last XR stat-summary was sent */ uint8_t max_ttl_or_hl_since_last_stat_summary; /* The maximum value of TTL/HL since last XR stat-summary was sent */
uint32_t first_rcv_seq;
uint32_t last_rcv_seq;
uint32_t rcv_count;
uint32_t discarded_count;
} OrtpRtcpXrStats; } OrtpRtcpXrStats;
typedef struct _RtpStream typedef struct _RtpStream
......
...@@ -587,7 +587,8 @@ static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) { ...@@ -587,7 +587,8 @@ static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) {
block->end_seq = htons(last_rcv_seq + 1); block->end_seq = htons(last_rcv_seq + 1);
block->lost_packets = htonl(lost_packets); block->lost_packets = htonl(lost_packets);
block->dup_packets = htonl(dup_packets); block->dup_packets = htonl(dup_packets);
if (flags & OrtpRtcpXrStatSummaryJitt) { if ((flags & OrtpRtcpXrStatSummaryJitt)
&& (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0)) {
block->min_jitter = htonl(session->rtcp_xr_stats.min_jitter_since_last_stat_summary); block->min_jitter = htonl(session->rtcp_xr_stats.min_jitter_since_last_stat_summary);
block->max_jitter = htonl(session->rtcp_xr_stats.max_jitter_since_last_stat_summary); block->max_jitter = htonl(session->rtcp_xr_stats.max_jitter_since_last_stat_summary);
block->mean_jitter = htonl((session->rtcp_xr_stats.rcv_since_last_stat_summary > 1) block->mean_jitter = htonl((session->rtcp_xr_stats.rcv_since_last_stat_summary > 1)
...@@ -600,7 +601,8 @@ static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) { ...@@ -600,7 +601,8 @@ static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) {
block->mean_jitter = htonl(0); block->mean_jitter = htonl(0);
block->dev_jitter = htonl(0); block->dev_jitter = htonl(0);
} }
if (flags & (OrtpRtcpXrStatSummaryTTL | OrtpRtcpXrStatSummaryHL)) { if ((flags & (OrtpRtcpXrStatSummaryTTL | OrtpRtcpXrStatSummaryHL))
&& (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0)) {
block->min_ttl_or_hl = session->rtcp_xr_stats.min_ttl_or_hl_since_last_stat_summary; block->min_ttl_or_hl = session->rtcp_xr_stats.min_ttl_or_hl_since_last_stat_summary;
block->max_ttl_or_hl = session->rtcp_xr_stats.max_ttl_or_hl_since_last_stat_summary; block->max_ttl_or_hl = session->rtcp_xr_stats.max_ttl_or_hl_since_last_stat_summary;
block->mean_ttl_or_hl = (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0) block->mean_ttl_or_hl = (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0)
...@@ -621,13 +623,71 @@ static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) { ...@@ -621,13 +623,71 @@ static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) {
return sizeof(rtcp_xr_stat_summary_report_block_t); return sizeof(rtcp_xr_stat_summary_report_block_t);
} }
static uint8_t calc_rate(double d1, double d2) {
double rate = (d1 / d2) * 256;
uint32_t int_rate = (uint32_t)rate;
if (int_rate > 255) int_rate = 255;
return (uint8_t)int_rate;
}
static int rtcp_xr_voip_metrics_init(uint8_t *buf, RtpSession *session) { static int rtcp_xr_voip_metrics_init(uint8_t *buf, RtpSession *session) {
JBParameters jbparams;
uint32_t expected_packets;
uint32_t lost_packets;
rtcp_xr_voip_metrics_report_block_t *block = (rtcp_xr_voip_metrics_report_block_t *)buf; rtcp_xr_voip_metrics_report_block_t *block = (rtcp_xr_voip_metrics_report_block_t *)buf;
float rtt = rtp_session_get_round_trip_propagation(session);
uint16_t int_rtt = (rtt >= 0) ? (rtt * 1000) : 0;
rtp_session_get_jitter_buffer_params(session, &jbparams);
block->bh.bt = RTCP_XR_VOIP_METRICS; block->bh.bt = RTCP_XR_VOIP_METRICS;
block->bh.flags = 0; // Reserved bits block->bh.flags = 0; // Reserved bits
block->bh.length = htons(8); block->bh.length = htons(8);
// TODO: Fill other fields from info in the session block->ssrc = htonl(rtp_session_get_recv_ssrc(session));
block->gmin = RTCP_XR_GMIN;
// Fill RX config
block->rx_config = 0;
if (jbparams.adaptive) {
block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_JBA_ADA;
} else {
block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_JBA_NON;
}
// TODO: fill PLC flags
// Fill JB fields
block->jb_nominal = htons((uint16_t)jbparams.nom_size);
if (jbparams.adaptive) {
block->jb_maximum = htons((session->rtp.jittctl.adapt_jitt_comp_ts * 1000) / session->rtp.jittctl.clock_rate);
} else {
block->jb_maximum = block->jb_nominal;
}
block->jb_abs_max = htons(65535);
if (session->rtcp_xr_stats.rcv_count > 0) {
expected_packets = session->rtcp_xr_stats.last_rcv_seq - session->rtcp_xr_stats.first_rcv_seq + 1;
lost_packets = expected_packets - session->rtcp_xr_stats.rcv_count;
block->loss_rate = calc_rate((double)lost_packets, (double)expected_packets);
block->discard_rate = calc_rate((double)session->rtcp_xr_stats.discarded_count, (double)expected_packets);
// TODO: fill burst_density, gap_density, burst_duration, gap_duration
block->round_trip_delay = htons(int_rtt);
} else {
block->loss_rate = 0;
block->discard_rate = 0;
block->burst_density = 0;
block->gap_density = 0;
block->burst_duration = htons(0);
block->gap_duration = htons(0);
block->round_trip_delay = htons(0);
block->end_system_delay = htons(0);
block->signal_level = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
block->noise_level = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
block->rerl = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
block->r_factor = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
block->ext_r_factor = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
block->mos_lq = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
block->mos_cq = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
}
return sizeof(rtcp_xr_voip_metrics_report_block_t); return sizeof(rtcp_xr_voip_metrics_report_block_t);
} }
......
...@@ -257,7 +257,9 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t ...@@ -257,7 +257,9 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
if (stats->packet_recv==1){ if (stats->packet_recv==1){
rtpstream->hwrcv_seq_at_last_SR=rtp->seq_number; rtpstream->hwrcv_seq_at_last_SR=rtp->seq_number;
session->rtcp_xr_stats.rcv_seq_at_last_stat_summary = rtp->seq_number; session->rtcp_xr_stats.rcv_seq_at_last_stat_summary = rtp->seq_number;
session->rtcp_xr_stats.first_rcv_seq = extseq->one;
} }
session->rtcp_xr_stats.last_rcv_seq = extseq->one;
} }
/* check for possible telephone events */ /* check for possible telephone events */
...@@ -265,6 +267,7 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t ...@@ -265,6 +267,7 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
queue_packet(&session->rtp.tev_rq,session->rtp.max_rq_size,mp,rtp,&discarded,&duplicate); queue_packet(&session->rtp.tev_rq,session->rtp.max_rq_size,mp,rtp,&discarded,&duplicate);
stats->discarded+=discarded; stats->discarded+=discarded;
ortp_global_stats.discarded+=discarded; ortp_global_stats.discarded+=discarded;
session->rtcp_xr_stats.discarded_count += discarded;
session->rtcp_xr_stats.dup_since_last_stat_summary += duplicate; session->rtcp_xr_stats.dup_since_last_stat_summary += duplicate;
return; return;
} }
...@@ -300,6 +303,7 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t ...@@ -300,6 +303,7 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
freemsg(mp); freemsg(mp);
stats->outoftime++; stats->outoftime++;
ortp_global_stats.outoftime++; ortp_global_stats.outoftime++;
session->rtcp_xr_stats.discarded_count++;
return; return;
} }
} }
...@@ -308,6 +312,10 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t ...@@ -308,6 +312,10 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
jitter_control_update_size(&session->rtp.jittctl,&session->rtp.rq); jitter_control_update_size(&session->rtp.jittctl,&session->rtp.rq);
stats->discarded+=discarded; stats->discarded+=discarded;
ortp_global_stats.discarded+=discarded; ortp_global_stats.discarded+=discarded;
session->rtcp_xr_stats.discarded_count += discarded;
session->rtcp_xr_stats.dup_since_last_stat_summary += duplicate; session->rtcp_xr_stats.dup_since_last_stat_summary += duplicate;
if ((discarded == 0) && (duplicate == 0)) {
session->rtcp_xr_stats.rcv_count++;
}
} }
...@@ -1169,6 +1169,7 @@ rtp_session_recvm_with_ts (RtpSession * session, uint32_t user_ts) ...@@ -1169,6 +1169,7 @@ rtp_session_recvm_with_ts (RtpSession * session, uint32_t user_ts)
stream->stats.outoftime+=rejected; stream->stats.outoftime+=rejected;
ortp_global_stats.outoftime+=rejected; ortp_global_stats.outoftime+=rejected;
session->rtcp_xr_stats.discarded_count += rejected;
goto end; goto end;
......
...@@ -22,6 +22,15 @@ ...@@ -22,6 +22,15 @@
#include "ortp/rtpsession.h" #include "ortp/rtpsession.h"
#define RTCP_XR_GMIN 16 /* Recommended value of Gmin from RFC3611, section 4.7.6 */
#define RTCP_XR_VOIP_METRICS_CONFIG_PLC_STD ((1 << 7) | (1 << 6))
#define RTCP_XR_VOIP_METRICS_CONFIG_PLC_ENH (1 << 7)
#define RTCP_XR_VOIP_METRICS_CONFIG_PLC_DIS (1 << 6)
#define RTCP_XR_VOIP_METRICS_CONFIG_PLC_UNS 0
#define RTCP_XR_VOIP_METRICS_CONFIG_JBA_ADA ((1 << 5) | (1 << 4))
#define RTCP_XR_VOIP_METRICS_CONFIG_JBA_NON (1 << 5)
#define RTCP_XR_VOIP_METRICS_CONFIG_JBA_UNK 0
typedef enum { typedef enum {
RTP_SESSION_RECV_SYNC=1, /* the rtp session is synchronising in the incoming stream */ RTP_SESSION_RECV_SYNC=1, /* the rtp session is synchronising in the incoming stream */
RTP_SESSION_FIRST_PACKET_DELIVERED=1<<1, RTP_SESSION_FIRST_PACKET_DELIVERED=1<<1,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment