From 90f4f8e4185a09713596d248ad0f1253cc2afccf Mon Sep 17 00:00:00 2001 From: Javier Montoro Date: Wed, 27 May 2026 12:02:17 +0200 Subject: [PATCH] MT#55283 differentiate sequence-gap based and rtcp based packets lost closes #2114 Change-Id: Ie218074c7ffbf5d23145e84709f0fbcb08d843f4 --- daemon/mqtt.c | 13 +++++++++++-- daemon/ssrc.c | 2 +- include/ssrc.h | 6 ++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/daemon/mqtt.c b/daemon/mqtt.c index 708e24a00..41e5b47dd 100644 --- a/daemon/mqtt.c +++ b/daemon/mqtt.c @@ -239,22 +239,24 @@ static void mqtt_ssrc_stats(struct ssrc_entry_call *ssrc, JsonBuilder *json, str json_builder_begin_object(json); // copy out values - int64_t packets, octets, packets_lost, duplicates; + int64_t packets, octets, packets_lost, packets_lost_rtcp, duplicates; packets = atomic64_get_na(&ssrc->stats->packets); octets = atomic64_get_na(&ssrc->stats->bytes); packets_lost = ssrc->packets_lost; + packets_lost_rtcp = ssrc->packets_lost_rtcp; duplicates = ssrc->duplicates; // process per-second stats int64_t cur_ts = rtpe_now; int64_t last_sample; - int64_t sample_packets, sample_octets, sample_packets_lost, sample_duplicates; + int64_t sample_packets, sample_octets, sample_packets_lost, sample_packets_lost_rtcp, sample_duplicates; // sample values last_sample = atomic64_get_set(&ssrc->last_sample, cur_ts); sample_packets = atomic64_get_set(&ssrc->sample_packets, packets); sample_octets = atomic64_get_set(&ssrc->sample_octets, octets); sample_packets_lost = atomic64_get_set(&ssrc->sample_packets_lost, packets_lost); + sample_packets_lost_rtcp = atomic64_get_set(&ssrc->sample_packets_lost_rtcp, packets_lost_rtcp); sample_duplicates = atomic64_get_set(&ssrc->sample_duplicates, duplicates); json_builder_set_member_name(json, "packets"); @@ -266,6 +268,9 @@ static void mqtt_ssrc_stats(struct ssrc_entry_call *ssrc, JsonBuilder *json, str json_builder_set_member_name(json, "lost"); json_builder_add_int_value(json, packets_lost); + json_builder_set_member_name(json, "lost_rtcp"); + json_builder_add_int_value(json, packets_lost_rtcp); + json_builder_set_member_name(json, "duplicates"); json_builder_add_int_value(json, duplicates); @@ -278,6 +283,7 @@ static void mqtt_ssrc_stats(struct ssrc_entry_call *ssrc, JsonBuilder *json, str packets -= sample_packets; octets -= sample_octets; packets_lost -= sample_packets_lost; + packets_lost_rtcp -= sample_packets_lost_rtcp; duplicates -= sample_duplicates; json_builder_set_member_name(json, "packets_per_second"); @@ -289,6 +295,9 @@ static void mqtt_ssrc_stats(struct ssrc_entry_call *ssrc, JsonBuilder *json, str json_builder_set_member_name(json, "lost_per_second"); json_builder_add_double_value(json, (double) packets_lost * 1000000.0 / usecs_diff); + json_builder_set_member_name(json, "lost_rtcp_per_second"); + json_builder_add_double_value(json, (double) packets_lost_rtcp * 1000000.0 / usecs_diff); + json_builder_set_member_name(json, "duplicates_per_second"); json_builder_add_double_value(json, (double) duplicates * 1000000.0 / usecs_diff); } diff --git a/daemon/ssrc.c b/daemon/ssrc.c index 4f5dc736a..b4a06c0a0 100644 --- a/daemon/ssrc.c +++ b/daemon/ssrc.c @@ -484,7 +484,7 @@ void ssrc_receiver_report(struct call_media *m, stream_fd *sfd, const struct ssr mos_calc = mos_calc_legacy; #endif - other_e->packets_lost = rr->packets_lost; + other_e->packets_lost_rtcp = rr->packets_lost; mos_calc(ssb); if (ssb->mos) { ilog(LOG_DEBUG, "Calculated MOS from RR for %s%x%s is %.1f", FMT_M(rr->from), diff --git a/include/ssrc.h b/include/ssrc.h index 15f627618..1ad5876d0 100644 --- a/include/ssrc.h +++ b/include/ssrc.h @@ -62,7 +62,8 @@ struct ssrc_entry_call { atomic64 last_sample, sample_packets, sample_octets, - sample_packets_lost, + sample_packets_lost, // local (sequence-gap based) + sample_packets_lost_rtcp, // as reported via RTCP RR sample_duplicates; int64_t next_rtcp; // for self-generated RTCP reports @@ -80,7 +81,8 @@ struct ssrc_entry_call { // input only - tracking for passthrough handling uint32_t last_seq_tracked; uint32_t lost_bits; // sliding bitfield, [0] = ext_seq - uint32_t packets_lost; // RTCP cumulative number of packets lost + uint32_t packets_lost; // locally measured (sequence-gap based) cumulative packets lost + uint32_t packets_lost_rtcp; // RTCP cumulative number of packets lost (RR) uint32_t duplicates; // for transcoding