Commit eb73ce02 authored by Ghislain MARY's avatar Ghislain MARY

Fill lost and duplicate fields in RTCP XR stat-summary packets.

parent fb7f4f8b
......@@ -140,6 +140,9 @@ typedef struct OrtpRtcpXrConfiguration {
typedef struct OrtpRtcpXrStats {
uint32_t last_rcvr_rtt_ts; /* NTP timestamp (middle 32 bits) of last received XR rcvr-rtt */
struct timeval last_rcvr_rtt_time; /* Time at which last XR rcvr-rtt was received */
uint16_t rcv_seq_at_last_stat_summary; /* Received sequence number at last XR stat-summary sent */
uint32_t rcv_since_last_stat_summary; /* The number of packets received since last XR stat-summary was sent */
uint32_t dup_since_last_stat_summary; /* The number of duplicate packets received since last XR stat-summary was sent */
} OrtpRtcpXrStats;
typedef struct _RtpStream
......
......@@ -565,11 +565,49 @@ static int rtcp_xr_dlrr_init(uint8_t *buf, RtpSession *session) {
static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) {
rtcp_xr_stat_summary_report_block_t *block = (rtcp_xr_stat_summary_report_block_t *)buf;
uint16_t last_rcv_seq = session->rtp.hwrcv_extseq & 0xFFFF;
uint8_t flags = session->rtcp.xr_conf.stat_summary_flags;
uint32_t expected_packets;
uint32_t lost_packets = 0;
uint32_t dup_packets = session->rtcp_xr_stats.dup_since_last_stat_summary;
/* Compute lost and duplicate packets statistics */
if (flags & OrtpRtcpXrStatSummaryLoss) {
uint32_t no_duplicate_received = session->rtcp_xr_stats.rcv_since_last_stat_summary - dup_packets;
expected_packets = last_rcv_seq - session->rtcp_xr_stats.rcv_seq_at_last_stat_summary;
lost_packets = (expected_packets > session->rtcp_xr_stats.rcv_since_last_stat_summary)
? (expected_packets - no_duplicate_received) : 0;
}
block->bh.bt = RTCP_XR_STAT_SUMMARY;
block->bh.flags = session->rtcp.xr_conf.stat_summary_flags;
block->bh.flags = flags;
block->bh.length = htons(9);
// TODO: Fill other fields from info in the session
block->ssrc = htonl(rtp_session_get_recv_ssrc(session));
block->begin_seq = htons(session->rtcp_xr_stats.rcv_seq_at_last_stat_summary + 1);
block->end_seq = htons(last_rcv_seq + 1);
block->lost_packets = htonl(lost_packets);
block->dup_packets = htonl(dup_packets);
if (flags & OrtpRtcpXrStatSummaryJitt) {
/* TODO */
} else {
block->min_jitter = htonl(0);
block->max_jitter = htonl(0);
block->mean_jitter = htonl(0);
block->dev_jitter = htonl(0);
}
if (flags & (OrtpRtcpXrStatSummaryTTL | OrtpRtcpXrStatSummaryHL)) {
/* TODO */
} else {
block->min_ttl_or_hl = 0;
block->max_ttl_or_hl = 0;
block->mean_ttl_or_hl = 0;
block->dev_ttl_or_hl = 0;
}
session->rtcp_xr_stats.rcv_seq_at_last_stat_summary = last_rcv_seq;
session->rtcp_xr_stats.rcv_since_last_stat_summary = 0;
session->rtcp_xr_stats.dup_since_last_stat_summary = 0;
return sizeof(rtcp_xr_stat_summary_report_block_t);
}
......
......@@ -23,11 +23,12 @@
#include "utils.h"
#include "rtpsession_priv.h"
static bool_t queue_packet(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rtp, int *discarded)
static bool_t queue_packet(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rtp, int *discarded, int *duplicate)
{
mblk_t *tmp;
int header_size;
*discarded=0;
*duplicate=0;
header_size=RTP_FIXED_HEADER_SIZE+ (4*rtp->cc);
if ((mp->b_wptr - mp->b_rptr)==header_size){
ortp_debug("Rtp packet contains no data.");
......@@ -35,9 +36,13 @@ static bool_t queue_packet(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rt
freemsg(mp);
return FALSE;
}
/* and then add the packet to the queue */
rtp_putq(q,mp);
if (rtp_putq(q,mp) < 0) {
/* It was a duplicate packet */
(*duplicate)++;
}
/* make some checks: q size must not exceed RtpStream::max_rq_size */
while (q->q_mcount > maxrqsz)
{
......@@ -56,6 +61,8 @@ static bool_t queue_packet(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rt
void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_ts, struct sockaddr *addr, socklen_t addrlen)
{
int i;
int discarded;
int duplicate;
rtp_header_t *rtp;
int msgsize;
RtpStream *rtpstream=&session->rtp;
......@@ -102,8 +109,8 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
ortp_global_stats.hw_recv+=msgsize;
stats->hw_recv+=msgsize;
session->rtp.hwrcv_since_last_SR++;
session->rtcp_xr_stats.rcv_since_last_stat_summary++;
/* convert all header data from network order to host order */
rtp->seq_number=ntohs(rtp->seq_number);
rtp->timestamp=ntohl(rtp->timestamp);
......@@ -189,14 +196,16 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
/* the first sequence number received should be initialized at the beginning, so that the first receiver reports contains valid loss rate*/
if (stats->packet_recv==1){
rtpstream->hwrcv_seq_at_last_SR=rtp->seq_number;
session->rtcp_xr_stats.rcv_seq_at_last_stat_summary = rtp->seq_number;
}
}
/* check for possible telephone events */
if (rtp->paytype==session->rcv.telephone_events_pt){
queue_packet(&session->rtp.tev_rq,session->rtp.max_rq_size,mp,rtp,&i);
stats->discarded+=i;
ortp_global_stats.discarded+=i;
queue_packet(&session->rtp.tev_rq,session->rtp.max_rq_size,mp,rtp,&discarded,&duplicate);
stats->discarded+=discarded;
ortp_global_stats.discarded+=discarded;
session->rtcp_xr_stats.dup_since_last_stat_summary += duplicate;
return;
}
......@@ -233,9 +242,10 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
}
}
if (queue_packet(&session->rtp.rq,session->rtp.max_rq_size,mp,rtp,&i))
if (queue_packet(&session->rtp.rq,session->rtp.max_rq_size,mp,rtp,&discarded,&duplicate))
jitter_control_update_size(&session->rtp.jittctl,&session->rtp.rq);
stats->discarded+=i;
ortp_global_stats.discarded+=i;
stats->discarded+=discarded;
ortp_global_stats.discarded+=discarded;
session->rtcp_xr_stats.dup_since_last_stat_summary += duplicate;
}
......@@ -109,8 +109,9 @@ static uint32_t uint32_t_random(){
#define RTP_SEQ_IS_GREATER(seq1,seq2)\
((uint16_t)((uint16_t)(seq1) - (uint16_t)(seq2))< (uint16_t)(1<<15))
/* put an rtp packet in queue. It is called by rtp_parse()*/
void rtp_putq(queue_t *q, mblk_t *mp)
/* put an rtp packet in queue. It is called by rtp_parse()
A return value of -1 means the packet was a duplicate, 0 means the packet was ok */
int rtp_putq(queue_t *q, mblk_t *mp)
{
mblk_t *tmp;
rtp_header_t *rtp=(rtp_header_t*)mp->b_rptr,*tmprtp;
......@@ -120,7 +121,7 @@ void rtp_putq(queue_t *q, mblk_t *mp)
if (qempty(q)) {
putq(q,mp);
return;
return 0;
}
tmp=qlast(q);
/* we look at the queue from bottom to top, because enqueued packets have a better chance
......@@ -130,23 +131,23 @@ void rtp_putq(queue_t *q, mblk_t *mp)
tmprtp=(rtp_header_t*)tmp->b_rptr;
ortp_debug("rtp_putq(): Seeing packet with seq=%i",tmprtp->seq_number);
if (rtp->seq_number == tmprtp->seq_number)
{
/* this is a duplicated packet. Don't queue it */
ortp_debug("rtp_putq: duplicated message.");
freemsg(mp);
return;
if (rtp->seq_number == tmprtp->seq_number)
{
/* this is a duplicated packet. Don't queue it */
ortp_debug("rtp_putq: duplicated message.");
freemsg(mp);
return -1;
}else if (RTP_SEQ_IS_GREATER(rtp->seq_number,tmprtp->seq_number)){
insq(q,tmp->b_next,mp);
return;
}
return 0;
}
tmp=tmp->b_prev;
}
/* this packet is the oldest, it has to be
placed on top of the queue */
insq(q,qfirst(q),mp);
return 0;
}
......
......@@ -44,7 +44,7 @@ typedef enum {
int rtp_session_rtp_recv_abstract(ortp_socket_t socket, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen);
void rtp_session_update_payload_type(RtpSession * session, int pt);
void rtp_putq(queue_t *q, mblk_t *mp);
int rtp_putq(queue_t *q, mblk_t *mp);
mblk_t * rtp_getq(queue_t *q, uint32_t ts, int *rejected);
int rtp_session_rtp_recv(RtpSession * session, uint32_t ts);
int rtp_session_rtcp_recv(RtpSession * session);
......
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