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 {