From 101d9ae0efeb345d6fc926fdb041e20945342313 Mon Sep 17 00:00:00 2001 From: Tom Briden Date: Wed, 28 May 2025 12:11:58 +0100 Subject: [PATCH] MT#55283 codec: fix not processing DTMF during block-media when audio sent along with DTMF this fixes an edge case where `DTMF-security=silence`, `block-media` is enabled and the endpoint sends silence packets in between each RTP event packet of a single DTMF hit. When that happens, the DTMF doesn't get processed as `packet_sequencer_next_packet` returns NULL, and the while loop is broken due to the ts_diff being 0 By checking if media is currently blocked and that the current packet is a supplemental DTMF, we can force the packet to be processed so the dropped packet is considered lost and we don't lose the DTMF event Change-Id: I78bc8e273e872b3ab88f7a84e26a79fad1793476 --- daemon/codec.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 9417b8173..7f14d22d3 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -2333,25 +2333,36 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa || !h->dest_pt.codec_def) break; - uint32_t ts_diff = packet_ts - ch->csch.last_ts; - - // if packet TS is larger than last tracked TS, we can force the next packet if packets were lost and the TS - // difference is too large. if packet TS is the same or lower (can happen for supplement codecs) we can wait - // for the next packet - if (ts_diff == 0 || ts_diff >= 0x80000000) - break; - - uint64_t ts_diff_us = ts_diff * 1000000LL / h->source_pt.clock_rate; - if (ts_diff_us >= 60000) { // arbitrary value + // it's possible to receive audio packets between dtmf event packets for the same event. if this is + // happening while media is being blocked, then packet_sequencer_next_packet will have returned NULL + // above. this check forces processing of the dtmf event while media blocking is enabled so they can + // be detected correctly and sent on dtmf-log-dest endpoints + if (h->source_pt.codec_def && h->source_pt.codec_def->supplemental && !handler_silence_block(h, mp)) { packet = packet_sequencer_force_next_packet(seq); if (!packet) break; - ilogs(transcoding, LOG_DEBUG, "Timestamp difference too large (%" PRIu64 " ms) after lost packet, " - "forcing next packet", ts_diff_us / 1000); - RTPE_STATS_INC(rtp_skips); } - else - break; + else { + uint32_t ts_diff = packet_ts - ch->csch.last_ts; + + // if packet TS is larger than last tracked TS, we can force the next packet if packets were lost and the TS + // difference is too large. if packet TS is the same or lower (can happen for supplement codecs) we can wait + // for the next packet + if (ts_diff == 0 || ts_diff >= 0x80000000) + break; + + uint64_t ts_diff_us = ts_diff * 1000000LL / h->source_pt.clock_rate; + if (ts_diff_us >= 60000) { // arbitrary value + packet = packet_sequencer_force_next_packet(seq); + if (!packet) + break; + ilogs(transcoding, LOG_DEBUG, "Timestamp difference too large (%" PRIu64 " ms) after lost packet, " + "forcing next packet", ts_diff_us / 1000); + RTPE_STATS_INC(rtp_skips); + } + else + break; + } } if (ch) {