From a2fc2055059eecac8dbba161c05ad76016fc4ea5 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 23 May 2025 10:10:00 -0400 Subject: [PATCH] MT#55283 add logic to discard old packets If DTX audio has already been produced for a particular timestamp and a late packet matching that timestamp is encountered, we should just discard the packet instead of immediately doing a timestamp reset. This prevents unwanted TS resets. Only do a timestamp reset if this happens multiple times in a row, as we don't want to have to discard too much audio. Change-Id: I46c8c20b08787f7e45145bd88463bb6878f36f15 --- daemon/codec.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/daemon/codec.c b/daemon/codec.c index 9d463b79d..baf3d98d3 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -132,6 +132,7 @@ struct dtx_buffer { unsigned long head_ts; uint32_t ssrc; int64_t start_us; + unsigned int discard_old_count; }; struct dtx_packet { struct transcode_packet *packet; @@ -3791,6 +3792,7 @@ static void __dtx_send_later(struct codec_timer *ct) { unsigned long ts; int p_left = 0; int64_t tv_diff = -1, ts_diff = 0; + bool discarded_old = false; mutex_lock(&dtxb->lock); @@ -3815,8 +3817,16 @@ static void __dtx_send_later(struct codec_timer *ct) { if (!dtxb->head_ts) ; // first packet - else if (ts_diff < 0) + else if (ts_diff_us < -100000 || dtxb->discard_old_count > 3) ilogs(dtx, LOG_DEBUG, "DTX timestamp reset (from %lu to %lu)", dtxb->head_ts, ts); + else if (ts_diff < 0 || (ts_diff == 0 && discarded_old)) { + ilogs(dtx, LOG_DEBUG, "Discarding old packet (TS %lu < %lu, %" PRId64 " ms old)", + ts, dtxb->head_ts, -ts_diff_us / 1000); + t_queue_pop_head(&dtxb->packets); + dtx_packet_free(dtxp); + discarded_old = true; + continue; // try again + } else if (ts_diff_us > MAX(20 * rtpe_config.dtx_delay_us, 200000)) ilogs(dtx, LOG_DEBUG, "DTX timestamp reset (from %lu to %lu = %" PRId64 " ms)", dtxb->head_ts, ts, ts_diff_us); @@ -3979,6 +3989,11 @@ static void __dtx_send_later(struct codec_timer *ct) { int ptime = dtxb->ptime; int64_t dtxb_start_us = dtxb->start_us; + if (discarded_old) + dtxb->discard_old_count++; + else + dtxb->discard_old_count = 0; + mutex_unlock(&dtxb->lock); rwlock_lock_r(&call->master_lock);