From 3eae4b3af3829a5a9a888ddd8cb06f748e25e055 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 10 Jun 2021 14:59:49 -0400 Subject: [PATCH] TT#14008 add MOS-LQ option Change-Id: I2cacceda1f910fb2ed74ccd9f17cde1bf50031b0 --- daemon/main.c | 10 ++++++++++ daemon/rtpengine.pod | 7 +++++++ daemon/ssrc.c | 5 ++++- include/main.h | 4 ++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/daemon/main.c b/daemon/main.c index 153290ad2..513e211b2 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -434,6 +434,7 @@ static void options(int *argc, char ***argv) { #ifdef HAVE_MQTT AUTO_CLEANUP_GBUF(mqtt_publish_scope); #endif + AUTO_CLEANUP_GBUF(mos); rwlock_lock_w(&rtpe_config.config_lock); @@ -554,6 +555,7 @@ static void options(int *argc, char ***argv) { { "mqtt-publish-interval",0,0,G_OPTION_ARG_INT, &rtpe_config.mqtt_publish_interval,"Publish timer interval", "MILLISECONDS"}, { "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"}, { NULL, } }; @@ -820,6 +822,14 @@ static void options(int *argc, char ***argv) { die("Invalid --mqtt-publish-scope option ('%s')", mqtt_publish_scope); } #endif + if (mos) { + if (!strcasecmp(mos, "cq")) + rtpe_config.mos = MOS_CQ; + else if (!strcmp(mos, "lq")) + rtpe_config.mos = MOS_LQ; + else + die("Invalid --mos option ('%s')", mos); + } rwlock_unlock_w(&rtpe_config.config_lock); } diff --git a/daemon/rtpengine.pod b/daemon/rtpengine.pod index 6c07df321..60888e11b 100644 --- a/daemon/rtpengine.pod +++ b/daemon/rtpengine.pod @@ -978,6 +978,13 @@ call participant, so usually 2 media per call) will be published to Mosquitto with stats for that call media every I milliseconds, plus one message every I milliseconds with global stats. +=item B<--mos=>B|B + +MOS calculation formula. Defaults to B (conversational quality) which takes +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. + =back =head1 INTERFACES diff --git a/daemon/ssrc.c b/daemon/ssrc.c index 315df6069..dfc9f230f 100644 --- a/daemon/ssrc.c +++ b/daemon/ssrc.c @@ -61,8 +61,11 @@ static void ssrc_entry_put(void *ep) { // returned as mos * 10 (i.e. 10 - 50 for 1.0 to 5.0) static void mos_calc(struct ssrc_stats_block *ssb) { - if (!ssb->rtt) + uint64_t rtt = ssb->rtt; + if (rtpe_config.mos == MOS_CQ && !rtt) return; // can not compute the MOS-CQ unless we have a valid RTT + else if (rtpe_config.mos == MOS_LQ) + rtt = 0; // ignore RTT // as per https://www.pingman.com/kb/article/how-is-mos-calculated-in-pingplotter-pro-50.html int eff_rtt = ssb->rtt / 1000 + ssb->jitter * 2 + 10; diff --git a/include/main.h b/include/main.h index cfdecc226..e33330984 100644 --- a/include/main.h +++ b/include/main.h @@ -143,6 +143,10 @@ struct rtpengine_config { MPS_CALL, MPS_MEDIA, } mqtt_publish_scope; + enum { + MOS_CQ = 0, + MOS_LQ, + } mos; };