From 730cc646a84739931a9b18fec2b659f46b0961d9 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 8 Dec 2021 12:48:17 -0500 Subject: [PATCH] TT#14008 eliminate duplicate DTMF reports when forking media With multiple media subscriptions, codec handlers are called consecutively, once for each forwarding chain, leading to DTMF events reported multiple times. The DTMF trigger must therefore keep track of the state in the upper media object, not in the codec handlers. Change-Id: I9ceaf406e093f25b7c037a325a0f2a7a91954922 --- daemon/call.c | 2 ++ daemon/codec.c | 25 ++++++++++++++----------- include/call.h | 4 ++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 76998dd7c..ffa7d858f 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -821,6 +821,7 @@ struct call_media *call_media_new(struct call *call) { med = uid_slice_alloc0(med, &call->medias); med->call = call; codec_store_init(&med->codecs, med); + mutex_init(&med->dtmf_lock); return med; } @@ -3332,6 +3333,7 @@ void call_media_free(struct call_media **mdp) { codec_handler_free(&md->t38_handler); t38_gateway_put(&md->t38_gateway); g_queue_clear_full(&md->sdp_attributes, free); + mutex_destroy(&md->dtmf_lock); g_slice_free1(sizeof(*md), md); *mdp = NULL; } diff --git a/daemon/codec.c b/daemon/codec.c index 1c2287d04..0a212a734 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -129,7 +129,6 @@ struct codec_ssrc_handler { int bytes_per_packet; unsigned long first_ts; // for output TS scaling unsigned long last_ts; // to detect input lag and handle lost packets - unsigned long ts_in; // for DTMF dupe detection struct timeval first_send; unsigned long first_send_ts; long output_skew; @@ -1748,17 +1747,21 @@ static struct codec_handler *__input_handler(struct codec_handler *h, struct med static int packet_dtmf(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch, struct transcode_packet *packet, struct media_packet *mp) { - if (ch->ts_in != packet->ts) { // ignore already processed events - int ret = dtmf_event(mp, packet->payload, ch->encoder_format.clockrate); - if (G_UNLIKELY(ret == -1)) // error - return -1; - if (ret == 1) { - // END event - ch->ts_in = packet->ts; - input_ch->dtmf_start_ts = 0; + { + LOCK(&mp->media->dtmf_lock); + + if (mp->media->dtmf_ts != packet->ts) { // ignore already processed events + int ret = dtmf_event(mp, packet->payload, ch->encoder_format.clockrate); + if (G_UNLIKELY(ret == -1)) // error + return -1; + if (ret == 1) { + // END event + mp->media->dtmf_ts = packet->ts; + input_ch->dtmf_start_ts = 0; + } + else + input_ch->dtmf_start_ts = packet->ts ? packet->ts : 1; } - else - input_ch->dtmf_start_ts = packet->ts ? packet->ts : 1; } int ret = 0; diff --git a/include/call.h b/include/call.h index bcfc81a1b..ad4441372 100644 --- a/include/call.h +++ b/include/call.h @@ -382,6 +382,10 @@ struct call_media { //struct codec_handler *dtmf_injector; struct t38_gateway *t38_gateway; struct codec_handler *t38_handler; + + mutex_t dtmf_lock; + unsigned long dtmf_ts; // TS of last processed end event + #ifdef WITH_TRANSCODING union { struct {