From 44bc0b90c8b97c6088804fa541ef80051130da27 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 24 Dec 2020 08:26:53 -0500 Subject: [PATCH] TT#99621 feed locally generated RTCP to stats tracker for MOS Change-Id: I545f306e0f16dc71e20e10ebd419795275f7e3b2 --- daemon/codec.c | 4 +++ daemon/rtcp.c | 54 ++++++++++++++++++++++++++++++++++++--- daemon/timerthread.c | 2 +- include/rtcp.h | 1 - utils/rtpengine-ng-client | 4 +-- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 291c13bf3..f20c14f92 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1533,6 +1533,10 @@ next: receiver->rtcp_handler = rtcp_sink_handler; __codec_rtcp_timer(receiver); } + if (MEDIA_ISSET(sink, RTCP_GEN)) { + sink->rtcp_handler = rtcp_sink_handler; + __codec_rtcp_timer(sink); + } } diff --git a/daemon/rtcp.c b/daemon/rtcp.c index 64909ddcd..1c327db83 100644 --- a/daemon/rtcp.c +++ b/daemon/rtcp.c @@ -1395,7 +1395,10 @@ void rtcp_init() { -GString *rtcp_sender_report(uint32_t ssrc, uint32_t ts, uint32_t packets, uint32_t octets, GQueue *rrs) { +static GString *rtcp_sender_report(struct ssrc_sender_report *ssr, + uint32_t ssrc, uint32_t ssrc_out, uint32_t ts, uint32_t packets, uint32_t octets, GQueue *rrs, + GQueue *srrs) +{ GString *ret = g_string_sized_new(128); g_string_set_size(ret, sizeof(struct sender_report_packet)); struct sender_report_packet *sr = (void *) ret->str; @@ -1410,6 +1413,16 @@ GString *rtcp_sender_report(uint32_t ssrc, uint32_t ts, uint32_t packets, uint32 .packet_count = htonl(packets), .octet_count = htonl(octets), }; + if (ssr) { + *ssr = (struct ssrc_sender_report) { + .ssrc = ssrc_out, + .ntp_msw = rtpe_now.tv_sec + 2208988800, + .ntp_lsw = (4294967295ULL * rtpe_now.tv_usec) / 1000000ULL, + .timestamp = ts, // XXX calculate from rtpe_now instead + .packet_count = packets, + .octet_count = octets, + }; + } // receiver reports int i = 0, n = 0; @@ -1448,6 +1461,22 @@ GString *rtcp_sender_report(uint32_t ssrc, uint32_t ts, uint32_t packets, uint32 .dlsr = htonl(tv_diff * 65536 / 1000000), .jitter = htonl(jitter >> 4), }; + + if (srrs) { + struct ssrc_receiver_report *srr = g_slice_alloc(sizeof(*srr)); + *srr = (struct ssrc_receiver_report) { + .from = ssrc_out, + .ssrc = s->ssrc_map_out ? : s->parent->h.ssrc, + .fraction_lost = lost * 256 / (tot + lost), + .packets_lost = lost, + .high_seq_received = atomic64_get(&s->last_seq), + .lsr = ntp_middle_bits, + .dlsr = tv_diff * 65536 / 1000000, + .jitter = jitter >> 4, + }; + g_queue_push_tail(srrs, srr); + } + n++; } ssrc_ctx_put(&s); @@ -1523,6 +1552,12 @@ void rtcp_send_report(struct call_media *media, struct ssrc_ctx *ssrc_out) { ps = next_ps; } + struct call_media *other_media = NULL; + if (ps->rtp_sink) + other_media = ps->rtp_sink->media; + else if (ps->rtcp_sink) + other_media = ps->rtcp_sink->media; + log_info_stream_fd(ps->selected_sfd); GQueue rrs = G_QUEUE_INIT; @@ -1531,14 +1566,27 @@ void rtcp_send_report(struct call_media *media, struct ssrc_ctx *ssrc_out) { ilog(LOG_DEBUG, "Generating and sending RTCP SR for %x and up to %i source(s)", ssrc_out->parent->h.ssrc, rrs.length); - GString *sr = rtcp_sender_report(ssrc_out->parent->h.ssrc, + struct ssrc_sender_report ssr; + GQueue srrs = G_QUEUE_INIT; + + GString *sr = rtcp_sender_report(&ssr, ssrc_out->parent->h.ssrc, + ssrc_out->ssrc_map_out ? : ssrc_out->parent->h.ssrc, atomic64_get(&ssrc_out->last_ts), atomic64_get(&ssrc_out->packets), atomic64_get(&ssrc_out->octets), - &rrs); + &rrs, &srrs); socket_sendto(&ps->selected_sfd->socket, sr->str, sr->len, &ps->endpoint); g_string_free(sr, TRUE); + + if (other_media) + ssrc_sender_report(other_media, &ssr, &rtpe_now); + struct ssrc_receiver_report *srr; + while ((srr = g_queue_pop_head(&srrs))) { + if (other_media) + ssrc_receiver_report(other_media, srr, &rtpe_now); + g_slice_free1(sizeof(*srr), srr); + } } diff --git a/daemon/timerthread.c b/daemon/timerthread.c index 936e65c7c..31a61b7cc 100644 --- a/daemon/timerthread.c +++ b/daemon/timerthread.c @@ -109,7 +109,7 @@ static int timerthread_queue_run_one(struct timerthread_queue *ttq, void timerthread_queue_run(void *ptr) { struct timerthread_queue *ttq = ptr; - ilog(LOG_DEBUG, "running timerthread_queue"); + //ilog(LOG_DEBUG, "running timerthread_queue"); struct timeval next_send = {0,}; diff --git a/include/rtcp.h b/include/rtcp.h index d177d3f47..ef4622621 100644 --- a/include/rtcp.h +++ b/include/rtcp.h @@ -38,7 +38,6 @@ rtcp_filter_func rtcp_avpf2avp_filter; void rtcp_init(void); -GString *rtcp_sender_report(uint32_t ssrc, uint32_t ts, uint32_t packets, uint32_t octets, GQueue *rrs); void rtcp_receiver_reports(GQueue *out, struct ssrc_hash *hash, struct call_monologue *ml); void rtcp_send_report(struct call_media *media, struct ssrc_ctx *ssrc_out); diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index 0368b7600..a1e4af5de 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -88,13 +88,13 @@ my $cmd = shift(@ARGV) or die; my %packet = (command => $cmd); -for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address,ptime,xmlrpc-callback,metadata,address,file,db-id,code,DTLS-fingerprint,ICE-lite,generate RTCP')) { +for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address,ptime,xmlrpc-callback,metadata,address,file,db-id,code,DTLS-fingerprint,ICE-lite')) { defined($options{$x}) and $packet{$x} = \$options{$x}; } for my $x (split(/,/, 'TOS,delete-delay')) { defined($options{$x}) and $packet{$x} = $options{$x}; } -for my $x (split(/,/, 'trust address,symmetric,asymmetric,unidirectional,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,pad crypto,generate mid,fragment,original sendrecv,symmetric codecs,asymmetric codecs,inject DTMF')) { +for my $x (split(/,/, 'trust address,symmetric,asymmetric,unidirectional,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,pad crypto,generate mid,fragment,original sendrecv,symmetric codecs,asymmetric codecs,inject DTMF,generate RTCP')) { defined($options{$x}) and push(@{$packet{flags}}, $x); } for my $x (split(/,/, 'origin,session connection')) {