From 4d5ff2401a8b28418e1ba4594766d30bc45b8863 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 16 Apr 2025 14:54:54 -0400 Subject: [PATCH] MT#55283 scale dtx timers Change-Id: I296b56b8f77349addf384bf8bc3896b0b799f4bd --- daemon/codec.c | 60 ++++++++++++++++++++++++++------------------------ daemon/main.c | 19 ++++++++++------ include/main.h | 8 +++---- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index a946af1f5..d50b0665c 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -2949,7 +2949,7 @@ void codec_init_payload_type(rtp_payload_type *pt, enum media_type type) { static int handler_func_passthrough_stub(struct codec_handler *h, struct media_packet *mp) { if (G_UNLIKELY(!mp->rtp)) return handler_func_passthrough(h, mp); - if (rtpe_config.dtx_delay) + if (rtpe_config.dtx_delay_us) return 0; return handler_func_passthrough_ssrc(h, mp); } @@ -3285,7 +3285,7 @@ static bool __dtx_should_do(struct codec_ssrc_handler *ch) { return false; if (!decoder_has_dtx(ch->decoder)) return false; - if (!rtpe_config.dtx_delay) + if (!rtpe_config.dtx_delay_us) return false; return true; } @@ -3333,7 +3333,7 @@ static bool __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *dec if (!dtxb->ssrc) dtxb->ssrc = mp->ssrc_in->parent->h.ssrc; dtxb->ct.next = mp->tv; - dtxb->ct.next += rtpe_config.dtx_delay * 1000; // XXX scale to micro + dtxb->ct.next += rtpe_config.dtx_delay_us; timerthread_obj_schedule_abs(&dtxb->ct.tt_obj, dtxb->ct.next); } @@ -3626,18 +3626,19 @@ out: static bool __dtx_drift_shift(struct dtx_buffer *dtxb, unsigned long ts, - long tv_diff, long ts_diff, + int64_t tv_diff, int64_t ts_diff, struct codec_ssrc_handler *ch) { bool discard = false; - if (tv_diff < rtpe_config.dtx_delay * 1000) { + if (tv_diff < rtpe_config.dtx_delay_us) { // timer underflow ilogs(dtx, LOG_DEBUG, "Packet reception time has caught up with DTX timer " - "(%li ms < %i ms), " - "pushing DTX timer forward my %i ms", - tv_diff / 1000, rtpe_config.dtx_delay, rtpe_config.dtx_shift); - dtxb->ct.next += rtpe_config.dtx_shift * 1000; // XXX scale to micro + "(%li ms < %" PRId64 " ms), " + "pushing DTX timer forward my %" PRId64 " ms", + tv_diff / 1000, rtpe_config.dtx_delay_us / 1000L, + rtpe_config.dtx_shift_us / 1000L); + dtxb->ct.next += rtpe_config.dtx_shift_us; } else if (ts_diff < dtxb->tspp) { // TS underflow @@ -3647,10 +3648,10 @@ static bool __dtx_drift_shift(struct dtx_buffer *dtxb, unsigned long ts, } else { ilogs(dtx, LOG_DEBUG, "Packet timestamps have caught up with DTX timer " - "(TS %lu, diff %li), " - "pushing DTX timer forward by %i ms and discarding packet", - ts, ts_diff, rtpe_config.dtx_shift); - dtxb->ct.next += rtpe_config.dtx_shift * 1000; + "(TS %lu, diff %" PRId64 ", " + "pushing DTX timer forward by %" PRId64 " ms and discarding packet", + ts, ts_diff, rtpe_config.dtx_shift_us / 1000L); + dtxb->ct.next += rtpe_config.dtx_shift_us; discard = true; } } @@ -3658,20 +3659,21 @@ static bool __dtx_drift_shift(struct dtx_buffer *dtxb, unsigned long ts, // inspect TS is most recent packet struct dtx_packet *dtxp_last = t_queue_peek_tail(&dtxb->packets); ts_diff = dtxp_last->packet ? dtxp_last->packet->ts - ts : 0; - long long ts_diff_us = (long long) ts_diff * 1000000 / dtxb->clockrate; - if (ts_diff_us >= (long long) rtpe_config.dtx_lag * 1000) { + int64_t ts_diff_us = ts_diff * 1000000L / dtxb->clockrate; + if (ts_diff_us >= (long long) rtpe_config.dtx_lag_us) { // overflow ilogs(dtx, LOG_DEBUG, "DTX timer queue overflowing (%i packets in queue, " - "%lli ms delay), speeding up DTX timer by %i ms", - dtxb->packets.length, ts_diff_us / 1000, rtpe_config.dtx_shift); - dtxb->ct.next -= rtpe_config.dtx_shift * 1000; + "%" PRId64 " ms delay), speeding up DTX timer by %" PRId64 " ms", + dtxb->packets.length, ts_diff_us / 1000, + rtpe_config.dtx_shift_us / 1000L); + dtxb->ct.next -= rtpe_config.dtx_shift_us; } } return discard; } static bool __dtx_drift_drop(struct dtx_buffer *dtxb, unsigned long ts, - long tv_diff, long ts_diff, + int64_t tv_diff, int64_t ts_diff, struct codec_ssrc_handler *ch) { bool discard = false; @@ -3684,7 +3686,7 @@ static bool __dtx_drift_drop(struct dtx_buffer *dtxb, unsigned long ts, } else { ilogs(dtx, LOG_DEBUG, "Packet timestamps have caught up with DTX timer " - "(TS %lu, diff %li), " + "(TS %lu, diff %" PRId64 "), " "adjusting input TS clock back by one frame (%i)", ts, ts_diff, dtxb->tspp); dtxb->head_ts -= dtxb->tspp; @@ -3694,11 +3696,11 @@ static bool __dtx_drift_drop(struct dtx_buffer *dtxb, unsigned long ts, // inspect TS is most recent packet struct dtx_packet *dtxp_last = t_queue_peek_tail(&dtxb->packets); ts_diff = dtxp_last->packet ? dtxp_last->packet->ts - ts : 0; - long long ts_diff_us = (long long) ts_diff * 1000000 / dtxb->clockrate; - if (ts_diff_us >= (long long) rtpe_config.dtx_lag * 1000) { + int64_t ts_diff_us = ts_diff * 1000000L / dtxb->clockrate; + if (ts_diff_us >= rtpe_config.dtx_lag_us) { // overflow ilogs(dtx, LOG_DEBUG, "DTX timer queue overflowing (%i packets in queue, " - "%lli ms delay), discarding packet", + "%" PRId64 " ms delay), discarding packet", dtxb->packets.length, ts_diff_us / 1000); discard = true; } @@ -3707,10 +3709,10 @@ static bool __dtx_drift_drop(struct dtx_buffer *dtxb, unsigned long ts, return discard; } static bool __dtx_handle_drift(struct dtx_buffer *dtxb, unsigned long ts, - long tv_diff, long ts_diff, + int64_t tv_diff, int64_t ts_diff, struct codec_ssrc_handler *ch) { - if (rtpe_config.dtx_shift) + if (rtpe_config.dtx_shift_us) return __dtx_drift_shift(dtxb, ts, tv_diff, ts_diff, ch); return __dtx_drift_drop(dtxb, ts, tv_diff, ts_diff, ch); } @@ -3741,14 +3743,14 @@ static void __dtx_send_later(struct codec_timer *ct) { // inspect head packet and check TS, see if it's ready to be decoded ts = dtxp->packet ? dtxp->packet->ts : dtxb->head_ts; ts_diff = ts - dtxb->head_ts; - long long ts_diff_us = (long long) ts_diff * 1000000 / dtxb->clockrate; + int64_t ts_diff_us = ts_diff * 1000000L / dtxb->clockrate; if (!dtxb->head_ts) ; // first packet else if (ts_diff < 0) ilogs(dtx, LOG_DEBUG, "DTX timestamp reset (from %lu to %lu)", dtxb->head_ts, ts); - else if (ts_diff_us > MAX(20 * rtpe_config.dtx_delay, 200000)) - ilogs(dtx, LOG_DEBUG, "DTX timestamp reset (from %lu to %lu = %lli ms)", + 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); else if (ts_diff >= dtxb->tspp * 2) { ilogs(dtx, LOG_DEBUG, "First packet in DTX buffer not ready yet (packet TS %lu, " @@ -3931,7 +3933,7 @@ static void __dtx_send_later(struct codec_timer *ct) { else { int64_t diff = rtpe_now - dtxb_start_us; - if (rtpe_config.max_dtx <= 0 || diff < rtpe_config.max_dtx * 1000000L) { // XXX scale to micro + if (rtpe_config.max_dtx_us <= 0 || diff < rtpe_config.max_dtx_us) { ilogs(dtx, LOG_DEBUG, "RTP media for TS %lu missing, triggering DTX", ts); // synthetic packet diff --git a/daemon/main.c b/daemon/main.c index 7f6cabff5..df844e79b 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -101,10 +101,7 @@ struct rtpengine_config rtpe_config = { .media_num_threads = -1, .dtls_rsa_key_size = 2048, .dtls_mtu = 1200, // chrome default mtu - .max_dtx = 30, - .dtx_shift = 5, .dtx_buffer = 10, - .dtx_lag = 100, .audio_buffer_delay = 5, .audio_buffer_length = 500, .mqtt_port = 1883, @@ -678,6 +675,10 @@ static void options(int *argc, char ***argv, charp_ht templates) { int rtcp_interval = 0; int redis_disable_time = 10; int mqtt_publish_interval = 5000; + int dtx_shift = 5; + int dtx_lag = 100; + int dtx_delay = 0; + int max_dtx = 30; GOptionEntry e[] = { { "table", 't', 0, G_OPTION_ARG_INT, &rtpe_config.kernel_table, "Kernel table to use", "INT" }, @@ -801,11 +802,11 @@ static void options(int *argc, char ***argv, charp_ht templates) { { "poller-per-thread", 0,0, G_OPTION_ARG_NONE, &rtpe_config.poller_per_thread, "Use poller per thread", NULL }, { "timer-accuracy", 0,0,G_OPTION_ARG_INT, &rtpe_config.timer_accuracy,"Minimum number of microseconds to sleep","INT"}, #ifdef WITH_TRANSCODING - { "dtx-delay", 0,0, G_OPTION_ARG_INT, &rtpe_config.dtx_delay, "Delay in milliseconds to trigger DTX handling","INT"}, - { "max-dtx", 0,0, G_OPTION_ARG_INT, &rtpe_config.max_dtx, "Maximum duration of DTX handling", "INT"}, + { "dtx-delay", 0,0, G_OPTION_ARG_INT, &dtx_delay, "Delay in milliseconds to trigger DTX handling","INT"}, + { "max-dtx", 0,0, G_OPTION_ARG_INT, &max_dtx, "Maximum duration of DTX handling", "INT"}, { "dtx-buffer", 0,0, G_OPTION_ARG_INT, &rtpe_config.dtx_buffer,"Maxmium number of packets held in DTX buffer", "INT"}, - { "dtx-lag", 0,0, G_OPTION_ARG_INT, &rtpe_config.dtx_lag, "Maxmium time span in milliseconds held in DTX buffer", "INT"}, - { "dtx-shift", 0,0, G_OPTION_ARG_INT, &rtpe_config.dtx_shift, "Length of time (in ms) to shift DTX buffer after over/underflow", "INT"}, + { "dtx-lag", 0,0, G_OPTION_ARG_INT, &dtx_lag, "Maxmium time span in milliseconds held in DTX buffer", "INT"}, + { "dtx-shift", 0,0, G_OPTION_ARG_INT, &dtx_shift, "Length of time (in ms) to shift DTX buffer after over/underflow", "INT"}, { "dtx-cn-params",0,0, G_OPTION_ARG_STRING_ARRAY,&dtx_cn_params, "Parameters for CN generated from DTX","INT INT INT ..."}, { "amr-dtx", 0,0, G_OPTION_ARG_STRING, &amr_dtx, "DTX mechanism to use for AMR and AMR-WB","native|CN"}, { "evs-dtx", 0,0, G_OPTION_ARG_STRING, &evs_dtx, "DTX mechanism to use for EVS","native|CN"}, @@ -1111,6 +1112,10 @@ static void options(int *argc, char ***argv, charp_ht templates) { rtpe_config.redis_disable_time_us = redis_disable_time * 1000000LL; rtpe_config.mqtt_publish_interval_us = mqtt_publish_interval * 1000LL; + rtpe_config.dtx_lag_us = dtx_lag * 1000LL; + rtpe_config.dtx_delay_us = dtx_delay * 1000LL; + rtpe_config.dtx_shift_us = dtx_shift * 1000LL; + rtpe_config.max_dtx_us = max_dtx * 1000000LL; if (redisps) { if (redis_ep_parse(&rtpe_config.redis_ep, &rtpe_config.redis_db, &rtpe_config.redis_hostname, diff --git a/include/main.h b/include/main.h index bdd79facb..4f9d171fe 100644 --- a/include/main.h +++ b/include/main.h @@ -71,11 +71,7 @@ enum endpoint_learning { X(dtls_rsa_key_size) \ X(dtls_mtu) \ X(http_threads) \ - X(dtx_delay) \ - X(max_dtx) \ X(dtx_buffer) \ - X(dtx_lag) \ - X(dtx_shift) \ X(kernel_player) \ X(kernel_player_media) \ X(audio_buffer_length) \ @@ -106,6 +102,10 @@ enum endpoint_learning { X(rtcp_interval_us) \ X(redis_disable_time_us) \ X(mqtt_publish_interval_us) \ + X(dtx_delay_us) \ + X(dtx_shift_us) \ + X(dtx_lag_us) \ + X(max_dtx_us) \ #define RTPE_CONFIG_BOOL_PARAMS \ X(homer_rtcp_off) \