From c1e0aa9dbf145476fe02ea83fbac9769d1b78484 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 5 Jul 2021 11:26:04 -0400 Subject: [PATCH] TT#121752 fix RTCP RR SSRC substitution when transcoding Perform reverse SSRC mapping even if output media is not known, and use the appropriate media side when looking up SSRCs for received RTCP timestamps. closes #1298 Change-Id: Ifa5a982163bf7b0510ffc2a92ae25995d1adb888 (cherry picked from commit 93377588ad530e49710ce623b1c7bf438580bc7c) --- daemon/rtcp.c | 5 ++++- daemon/ssrc.c | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/daemon/rtcp.c b/daemon/rtcp.c index bbf29f0b2..2c87900a4 100644 --- a/daemon/rtcp.c +++ b/daemon/rtcp.c @@ -1307,7 +1307,7 @@ static void transcode_rr(struct rtcp_process_ctx *ctx, struct report_block *rr) return; if (ctx->scratch.rr.from != ctx->mp->ssrc_in->parent->h.ssrc) return; - if (!ctx->mp->media || !ctx->mp->media_out) + if (!ctx->mp->media) return; // reverse SSRC mapping @@ -1315,6 +1315,9 @@ static void transcode_rr(struct rtcp_process_ctx *ctx, struct report_block *rr) SSRC_DIR_OUTPUT, ctx->mp->media->monologue); rr->ssrc = htonl(map_ctx->ssrc_map_out); + if (!ctx->mp->media_out) + return; + // for reception stats struct ssrc_ctx *input_ctx = get_ssrc_ctx(map_ctx->ssrc_map_out, ctx->mp->media_out->monologue->ssrc_hash, diff --git a/daemon/ssrc.c b/daemon/ssrc.c index d67083d70..64ad46747 100644 --- a/daemon/ssrc.c +++ b/daemon/ssrc.c @@ -84,7 +84,7 @@ static void mos_calc(struct ssrc_stats_block *ssb) { ssb->mos = intmos; } -static struct ssrc_entry *find_ssrc(uint32_t ssrc, struct ssrc_hash *ht) { +static void *find_ssrc(uint32_t ssrc, struct ssrc_hash *ht) { rwlock_lock_r(&ht->lock); struct ssrc_entry *ret = g_atomic_pointer_get(&ht->cache); if (!ret || ret->ssrc != ssrc) { @@ -257,14 +257,25 @@ static long long __calc_rtt(struct call_monologue *ml, uint32_t ssrc, uint32_t n if (!ntp_middle_bits || !delay) return 0; + if (!ml->active_dialogue) + return 0; - struct ssrc_entry_call *e = get_ssrc(ssrc, ml->ssrc_hash); + struct ssrc_entry_call *e = find_ssrc(ssrc, ml->active_dialogue->ssrc_hash); if (G_UNLIKELY(!e)) return 0; if (pt_p) *pt_p = e->output_ctx.tracker.most[0] == 255 ? -1 : e->output_ctx.tracker.most[0]; + // grab the opposite side SSRC for the time reports + uint32_t map_ssrc = e->output_ctx.ssrc_map_out; + if (!map_ssrc) + map_ssrc = e->h.ssrc; + obj_put(&e->h); + e = find_ssrc(map_ssrc, ml->ssrc_hash); + if (G_UNLIKELY(!e)) + return 0; + struct ssrc_time_item *sti; GQueue *q = (((void *) e) + reports_queue_offset); mutex_lock(&e->h.lock);