Browse Source

MT#55283 scale dtx timers

Change-Id: I296b56b8f77349addf384bf8bc3896b0b799f4bd
pull/1938/head
Richard Fuchs 8 months ago
parent
commit
4d5ff2401a
3 changed files with 47 additions and 40 deletions
  1. +31
    -29
      daemon/codec.c
  2. +12
    -7
      daemon/main.c
  3. +4
    -4
      include/main.h

+ 31
- 29
daemon/codec.c View File

@ -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


+ 12
- 7
daemon/main.c View File

@ -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,


+ 4
- 4
include/main.h View File

@ -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) \


Loading…
Cancel
Save