diff --git a/daemon/call.c b/daemon/call.c index 2ebe3ba30..c737f61e7 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -242,6 +242,10 @@ next: for (it = c->medias.head; it; it = it->next) { struct call_media *media = it->data; + if (rtpe_config.measure_rtp) { + media_update_stats(media); + ssrc_collect_metrics(media); + } if (MEDIA_ISSET(media, TRANSCODE)) hlp->transcoded_media++; } diff --git a/daemon/main.c b/daemon/main.c index a8f13302b..2f7019f6e 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -573,6 +573,7 @@ static void options(int *argc, char ***argv) { { "mqtt-publish-scope",0,0,G_OPTION_ARG_STRING, &mqtt_publish_scope, "Scope for published mosquitto messages","global|call|media"}, #endif { "mos",0,0, G_OPTION_ARG_STRING, &mos, "Type of MOS calculation","CQ|LQ"}, + { "measure-rtp",0,0, G_OPTION_ARG_NONE, &rtpe_config.measure_rtp,"Enable measuring RTP statistics and VoIP metrics",NULL}, #ifdef SO_INCOMING_CPU { "socket-cpu-affinity",0,0,G_OPTION_ARG_INT, &rtpe_config.cpu_affinity,"CPU affinity for media sockets","INT"}, #endif diff --git a/daemon/media_socket.c b/daemon/media_socket.c index ae209a296..87bca15aa 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1224,7 +1224,8 @@ static const char *kernelize_one(struct rtpengine_target_info *reti, GQueue *out reti->stun = media->ice_agent ? 1 : 0; reti->non_forwarding = non_forwarding ? 1 : 0; reti->blackhole = blackhole ? 1 : 0; - reti->rtp_stats = (MEDIA_ISSET(media, RTCP_GEN) || (mqtt_publish_scope() != MPS_NONE)) ? 1 : 0; + reti->rtp_stats = (rtpe_config.measure_rtp + || MEDIA_ISSET(media, RTCP_GEN) || (mqtt_publish_scope() != MPS_NONE)) ? 1 : 0; handler->in->kernel(&reti->decrypt, stream); if (!reti->decrypt.cipher || !reti->decrypt.hmac) @@ -1477,6 +1478,8 @@ static void __stream_update_stats(struct packet_stream *ps, int have_in_lock) { atomic64_set(&ssrc_ctx->last_ts, stats_info.ssrc_stats[u].timestamp); parent->jitter = stats_info.ssrc_stats[u].jitter; + RTPE_STATS_ADD(packets_lost, stats_info.ssrc_stats[u].total_lost); + uint32_t ssrc_map_out = ssrc_ctx->ssrc_map_out; // update opposite outgoing SSRC diff --git a/daemon/rtcp.c b/daemon/rtcp.c index bc249d70c..3c574a0ca 100644 --- a/daemon/rtcp.c +++ b/daemon/rtcp.c @@ -1544,7 +1544,6 @@ void rtcp_receiver_reports(GQueue *out, struct ssrc_hash *hash, struct call_mono rwlock_lock_r(&hash->lock); for (GList *l = hash->q.head; l; l = l->next) { struct ssrc_entry_call *e = l->data; - //ilog(LOG_DEBUG, "xxxxx %x %i %i %p %p %p", e->h.ssrc, (int) atomic64_get(&e->input_ctx.packets), (int) atomic64_get(&e->output_ctx.packets), ml, e->input_ctx.ref, e->output_ctx.ref); struct ssrc_ctx *i = &e->input_ctx; if (i->ref != ml) continue; diff --git a/daemon/rtpengine.pod b/daemon/rtpengine.pod index 96d200268..ac267cd7b 100644 --- a/daemon/rtpengine.pod +++ b/daemon/rtpengine.pod @@ -1033,6 +1033,11 @@ RTT into account and therefore requires peers to correctly send RTCP. If set to B (listening quality) RTT is ignored, allowing a MOS to be calculated in the absence of RTCP. +=item B<--measure-rtp> + +Enable measuring RTP metrics even for plain RTP passthrough scenarios. Without +that option, RTP metrics are measured only in transcoding scenarios. + =item B<--socket-cpu-affinity=>I Enables setting the socket CPU affinity via the B socket diff --git a/daemon/ssrc.c b/daemon/ssrc.c index d4bc5ab18..448fb2598 100644 --- a/daemon/ssrc.c +++ b/daemon/ssrc.c @@ -599,3 +599,30 @@ void payload_tracker_add(struct payload_tracker *t, int pt) { out: mutex_unlock(&t->lock); } + + +// call master lock held in R +void ssrc_collect_metrics(struct call_media *media) { + if (!media->streams.head) + return; + struct packet_stream *ps = media->streams.head->data; + for (int i = 0; i < RTPE_NUM_SSRC_TRACKING; i++) { + struct ssrc_ctx *s = ps->ssrc_in[i]; + if (!s) + break; // end of list + struct ssrc_entry_call *e = s->parent; + + // exclude zero values - technically possible but unlikely and probably just unset + if (!e->jitter) + continue; + + if (e->input_ctx.tracker.most_len > 0 && e->input_ctx.tracker.most[0] != 255) { + const struct rtp_payload_type *rpt = rtp_payload_type(e->input_ctx.tracker.most[0], + &ps->media->codecs); + if (rpt && rpt->clock_rate) + e->jitter = e->jitter * 1000 / rpt->clock_rate; + } + + RTPE_GAUGE_SET(jitter_measured, e->jitter); + } +} diff --git a/daemon/statistics.c b/daemon/statistics.c index c46672d47..12c72231c 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -553,10 +553,11 @@ GQueue *statistics_gather_metrics(void) { HEADER("voip_metrics", "VoIP metrics:"); HEADER("{", ""); - STAT_GET_PRINT(jitter, "jitter", 1.0); + STAT_GET_PRINT(jitter, "jitter (reported)", 1.0); STAT_GET_PRINT(rtt_e2e, "end-to-end round-trip time", 1.0); STAT_GET_PRINT(rtt_dsct, "discrete round-trip time", 1.0); STAT_GET_PRINT(packetloss, "packet loss", 1.0); + STAT_GET_PRINT(jitter_measured, "jitter (measured)", 1.0); HEADER(NULL, ""); HEADER("}", ""); diff --git a/include/counter_stats_fields.inc b/include/counter_stats_fields.inc index 7d130ff8d..f442a9356 100644 --- a/include/counter_stats_fields.inc +++ b/include/counter_stats_fields.inc @@ -19,3 +19,4 @@ F(oneway_stream_sess) F(call_duration) F(call_duration2) F(total_calls_duration_intv) +F(packets_lost) diff --git a/include/gauge_stats_fields.inc b/include/gauge_stats_fields.inc index de07c1129..9a88047ef 100644 --- a/include/gauge_stats_fields.inc +++ b/include/gauge_stats_fields.inc @@ -13,3 +13,4 @@ F(jitter) F(rtt_e2e) F(rtt_dsct) F(packetloss) +F(jitter_measured) diff --git a/include/main.h b/include/main.h index 5ad998ac1..c5e3b051a 100644 --- a/include/main.h +++ b/include/main.h @@ -156,6 +156,7 @@ struct rtpengine_config { MOS_CQ = 0, MOS_LQ, } mos; + int measure_rtp; int cpu_affinity; char *janus_secret; }; diff --git a/include/ssrc.h b/include/ssrc.h index 35da724e3..dec946743 100644 --- a/include/ssrc.h +++ b/include/ssrc.h @@ -227,6 +227,9 @@ void ssrc_voip_metrics(struct call_media *m, const struct ssrc_xr_voip_metrics * const struct timeval *); +void ssrc_collect_metrics(struct call_media *); + + void payload_tracker_init(struct payload_tracker *t); void payload_tracker_add(struct payload_tracker *, int); diff --git a/t/test-stats.c b/t/test-stats.c index ab0a59e09..44395c037 100644 --- a/t/test-stats.c +++ b/t/test-stats.c @@ -904,23 +904,23 @@ int main(void) { "voip_metrics\n" "\n" "{\n" - "Sum of all jitter values sampled\n" + "Sum of all jitter (reported) values sampled\n" "jitter_total\n" "0.000000\n" "0.000000\n" - "Sum of all jitter square values sampled\n" + "Sum of all jitter (reported) square values sampled\n" "jitter2_total\n" "0.000000\n" "0.000000\n" - "Total number of jitter samples\n" + "Total number of jitter (reported) samples\n" "jitter_samples_total\n" "0\n" "0\n" - "Average jitter\n" + "Average jitter (reported)\n" "jitter_average\n" "0.000000\n" "0.000000\n" - "jitter standard deviation\n" + "jitter (reported) standard deviation\n" "jitter_stddev\n" "0.000000\n" "0.000000\n" @@ -984,6 +984,26 @@ int main(void) { "packetloss_stddev\n" "0.000000\n" "0.000000\n" + "Sum of all jitter (measured) values sampled\n" + "jitter_measured_total\n" + "0.000000\n" + "0.000000\n" + "Sum of all jitter (measured) square values sampled\n" + "jitter_measured2_total\n" + "0.000000\n" + "0.000000\n" + "Total number of jitter (measured) samples\n" + "jitter_measured_samples_total\n" + "0\n" + "0\n" + "Average jitter (measured)\n" + "jitter_measured_average\n" + "0.000000\n" + "0.000000\n" + "jitter (measured) standard deviation\n" + "jitter_measured_stddev\n" + "0.000000\n" + "0.000000\n" "\n" "\n" "}\n" @@ -1892,23 +1912,23 @@ int main(void) { "voip_metrics\n" "\n" "{\n" - "Sum of all jitter values sampled\n" + "Sum of all jitter (reported) values sampled\n" "jitter_total\n" "0.000000\n" "0.000000\n" - "Sum of all jitter square values sampled\n" + "Sum of all jitter (reported) square values sampled\n" "jitter2_total\n" "0.000000\n" "0.000000\n" - "Total number of jitter samples\n" + "Total number of jitter (reported) samples\n" "jitter_samples_total\n" "0\n" "0\n" - "Average jitter\n" + "Average jitter (reported)\n" "jitter_average\n" "0.000000\n" "0.000000\n" - "jitter standard deviation\n" + "jitter (reported) standard deviation\n" "jitter_stddev\n" "0.000000\n" "0.000000\n" @@ -1972,6 +1992,26 @@ int main(void) { "packetloss_stddev\n" "0.000000\n" "0.000000\n" + "Sum of all jitter (measured) values sampled\n" + "jitter_measured_total\n" + "0.000000\n" + "0.000000\n" + "Sum of all jitter (measured) square values sampled\n" + "jitter_measured2_total\n" + "0.000000\n" + "0.000000\n" + "Total number of jitter (measured) samples\n" + "jitter_measured_samples_total\n" + "0\n" + "0\n" + "Average jitter (measured)\n" + "jitter_measured_average\n" + "0.000000\n" + "0.000000\n" + "jitter (measured) standard deviation\n" + "jitter_measured_stddev\n" + "0.000000\n" + "0.000000\n" "\n" "\n" "}\n" @@ -2877,23 +2917,23 @@ int main(void) { "voip_metrics\n" "\n" "{\n" - "Sum of all jitter values sampled\n" + "Sum of all jitter (reported) values sampled\n" "jitter_total\n" "0.000000\n" "0.000000\n" - "Sum of all jitter square values sampled\n" + "Sum of all jitter (reported) square values sampled\n" "jitter2_total\n" "0.000000\n" "0.000000\n" - "Total number of jitter samples\n" + "Total number of jitter (reported) samples\n" "jitter_samples_total\n" "0\n" "0\n" - "Average jitter\n" + "Average jitter (reported)\n" "jitter_average\n" "0.000000\n" "0.000000\n" - "jitter standard deviation\n" + "jitter (reported) standard deviation\n" "jitter_stddev\n" "0.000000\n" "0.000000\n" @@ -2957,6 +2997,26 @@ int main(void) { "packetloss_stddev\n" "0.000000\n" "0.000000\n" + "Sum of all jitter (measured) values sampled\n" + "jitter_measured_total\n" + "0.000000\n" + "0.000000\n" + "Sum of all jitter (measured) square values sampled\n" + "jitter_measured2_total\n" + "0.000000\n" + "0.000000\n" + "Total number of jitter (measured) samples\n" + "jitter_measured_samples_total\n" + "0\n" + "0\n" + "Average jitter (measured)\n" + "jitter_measured_average\n" + "0.000000\n" + "0.000000\n" + "jitter (measured) standard deviation\n" + "jitter_measured_stddev\n" + "0.000000\n" + "0.000000\n" "\n" "\n" "}\n" @@ -3875,23 +3935,23 @@ int main(void) { "voip_metrics\n" "\n" "{\n" - "Sum of all jitter values sampled\n" + "Sum of all jitter (reported) values sampled\n" "jitter_total\n" "0.000000\n" "0.000000\n" - "Sum of all jitter square values sampled\n" + "Sum of all jitter (reported) square values sampled\n" "jitter2_total\n" "0.000000\n" "0.000000\n" - "Total number of jitter samples\n" + "Total number of jitter (reported) samples\n" "jitter_samples_total\n" "0\n" "0\n" - "Average jitter\n" + "Average jitter (reported)\n" "jitter_average\n" "0.000000\n" "0.000000\n" - "jitter standard deviation\n" + "jitter (reported) standard deviation\n" "jitter_stddev\n" "0.000000\n" "0.000000\n" @@ -3955,6 +4015,26 @@ int main(void) { "packetloss_stddev\n" "0.000000\n" "0.000000\n" + "Sum of all jitter (measured) values sampled\n" + "jitter_measured_total\n" + "0.000000\n" + "0.000000\n" + "Sum of all jitter (measured) square values sampled\n" + "jitter_measured2_total\n" + "0.000000\n" + "0.000000\n" + "Total number of jitter (measured) samples\n" + "jitter_measured_samples_total\n" + "0\n" + "0\n" + "Average jitter (measured)\n" + "jitter_measured_average\n" + "0.000000\n" + "0.000000\n" + "jitter (measured) standard deviation\n" + "jitter_measured_stddev\n" + "0.000000\n" + "0.000000\n" "\n" "\n" "}\n" @@ -4868,23 +4948,23 @@ int main(void) { "voip_metrics\n" "\n" "{\n" - "Sum of all jitter values sampled\n" + "Sum of all jitter (reported) values sampled\n" "jitter_total\n" "0.000000\n" "0.000000\n" - "Sum of all jitter square values sampled\n" + "Sum of all jitter (reported) square values sampled\n" "jitter2_total\n" "0.000000\n" "0.000000\n" - "Total number of jitter samples\n" + "Total number of jitter (reported) samples\n" "jitter_samples_total\n" "0\n" "0\n" - "Average jitter\n" + "Average jitter (reported)\n" "jitter_average\n" "0.000000\n" "0.000000\n" - "jitter standard deviation\n" + "jitter (reported) standard deviation\n" "jitter_stddev\n" "0.000000\n" "0.000000\n" @@ -4948,6 +5028,26 @@ int main(void) { "packetloss_stddev\n" "0.000000\n" "0.000000\n" + "Sum of all jitter (measured) values sampled\n" + "jitter_measured_total\n" + "0.000000\n" + "0.000000\n" + "Sum of all jitter (measured) square values sampled\n" + "jitter_measured2_total\n" + "0.000000\n" + "0.000000\n" + "Total number of jitter (measured) samples\n" + "jitter_measured_samples_total\n" + "0\n" + "0\n" + "Average jitter (measured)\n" + "jitter_measured_average\n" + "0.000000\n" + "0.000000\n" + "jitter (measured) standard deviation\n" + "jitter_measured_stddev\n" + "0.000000\n" + "0.000000\n" "\n" "\n" "}\n" @@ -5856,23 +5956,23 @@ int main(void) { "voip_metrics\n" "\n" "{\n" - "Sum of all jitter values sampled\n" + "Sum of all jitter (reported) values sampled\n" "jitter_total\n" "0.000000\n" "0.000000\n" - "Sum of all jitter square values sampled\n" + "Sum of all jitter (reported) square values sampled\n" "jitter2_total\n" "0.000000\n" "0.000000\n" - "Total number of jitter samples\n" + "Total number of jitter (reported) samples\n" "jitter_samples_total\n" "0\n" "0\n" - "Average jitter\n" + "Average jitter (reported)\n" "jitter_average\n" "0.000000\n" "0.000000\n" - "jitter standard deviation\n" + "jitter (reported) standard deviation\n" "jitter_stddev\n" "0.000000\n" "0.000000\n" @@ -5936,6 +6036,26 @@ int main(void) { "packetloss_stddev\n" "0.000000\n" "0.000000\n" + "Sum of all jitter (measured) values sampled\n" + "jitter_measured_total\n" + "0.000000\n" + "0.000000\n" + "Sum of all jitter (measured) square values sampled\n" + "jitter_measured2_total\n" + "0.000000\n" + "0.000000\n" + "Total number of jitter (measured) samples\n" + "jitter_measured_samples_total\n" + "0\n" + "0\n" + "Average jitter (measured)\n" + "jitter_measured_average\n" + "0.000000\n" + "0.000000\n" + "jitter (measured) standard deviation\n" + "jitter_measured_stddev\n" + "0.000000\n" + "0.000000\n" "\n" "\n" "}\n" @@ -6846,23 +6966,23 @@ int main(void) { "voip_metrics\n" "\n" "{\n" - "Sum of all jitter values sampled\n" + "Sum of all jitter (reported) values sampled\n" "jitter_total\n" "0.000000\n" "0.000000\n" - "Sum of all jitter square values sampled\n" + "Sum of all jitter (reported) square values sampled\n" "jitter2_total\n" "0.000000\n" "0.000000\n" - "Total number of jitter samples\n" + "Total number of jitter (reported) samples\n" "jitter_samples_total\n" "0\n" "0\n" - "Average jitter\n" + "Average jitter (reported)\n" "jitter_average\n" "0.000000\n" "0.000000\n" - "jitter standard deviation\n" + "jitter (reported) standard deviation\n" "jitter_stddev\n" "0.000000\n" "0.000000\n" @@ -6926,6 +7046,26 @@ int main(void) { "packetloss_stddev\n" "0.000000\n" "0.000000\n" + "Sum of all jitter (measured) values sampled\n" + "jitter_measured_total\n" + "0.000000\n" + "0.000000\n" + "Sum of all jitter (measured) square values sampled\n" + "jitter_measured2_total\n" + "0.000000\n" + "0.000000\n" + "Total number of jitter (measured) samples\n" + "jitter_measured_samples_total\n" + "0\n" + "0\n" + "Average jitter (measured)\n" + "jitter_measured_average\n" + "0.000000\n" + "0.000000\n" + "jitter (measured) standard deviation\n" + "jitter_measured_stddev\n" + "0.000000\n" + "0.000000\n" "\n" "\n" "}\n"