From 64670ffb6175c75caedb58062f986b60bb9279f0 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 17 May 2021 14:34:47 -0400 Subject: [PATCH] TT#122401 add option to bypass AMR SID Change-Id: I0504d452737573f388941dcca507e3adfd5744c6 --- daemon/codec.c | 10 ++++++++-- daemon/main.c | 10 ++++++++++ daemon/rtpengine.pod | 12 ++++++++++++ include/main.h | 1 + lib/codeclib.c | 23 +++++++++++++++++++++-- lib/codeclib.h | 5 ++++- 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index dd6060a85..89d4e7d27 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -2835,8 +2835,14 @@ static struct ssrc_entry *__ssrc_handler_transcode_new(void *p) { &ch->encoder_format, &h->source_pt.format_parameters, &h->source_pt.codec_opts); if (!ch->decoder) goto err; - if (rtpe_config.dtx_cn_params.len) - decoder_set_cn_dtx(ch->decoder, &rtpe_config.dtx_cn_params); + if (rtpe_config.dtx_cn_params.len) { + if (ch->decoder->def->amr) { + if (rtpe_config.amr_cn_dtx) + decoder_set_cn_dtx(ch->decoder, &rtpe_config.dtx_cn_params); + } + else + decoder_set_cn_dtx(ch->decoder, &rtpe_config.dtx_cn_params); + } ch->decoder->event_data = h->media; ch->decoder->event_func = codec_decoder_event; diff --git a/daemon/main.c b/daemon/main.c index 0a44c7bd0..10bd2f4d4 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -423,6 +423,7 @@ static void options(int *argc, char ***argv) { AUTO_CLEANUP_GVBUF(cn_payload); AUTO_CLEANUP_GVBUF(dtx_cn_params); int debug_srtp = 0; + AUTO_CLEANUP_GBUF(amr_dtx); rwlock_lock_w(&rtpe_config.config_lock); @@ -522,6 +523,7 @@ static void options(int *argc, char ***argv) { { "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-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"}, { "silence-detect",0,0, G_OPTION_ARG_DOUBLE, &silence_detect, "Audio level threshold in percent for silence detection","FLOAT"}, { "cn-payload",0,0, G_OPTION_ARG_STRING_ARRAY,&cn_payload, "Comfort noise parameters to replace silence with","INT INT INT ..."}, { "reorder-codecs",0,0, G_OPTION_ARG_NONE, &rtpe_config.reorder_codecs,"Reorder answer codecs based on sender preference",NULL}, @@ -768,6 +770,14 @@ static void options(int *argc, char ***argv) { parse_cn_payload(&rtpe_config.cn_payload, cn_payload, "\x20", "cn-payload"); parse_cn_payload(&rtpe_config.dtx_cn_params, dtx_cn_params, NULL, "dtx-cn-params"); + if (amr_dtx) { + if (!strcasecmp(amr_dtx, "native")) {} + else if (!strcasecmp(amr_dtx, "CN")) + rtpe_config.amr_cn_dtx = 1; + else + die("Invalid --amr-dtx ('%s')", amr_dtx); + } + if (!rtpe_config.software_id) rtpe_config.software_id = g_strdup_printf("rtpengine-%s", RTPENGINE_VERSION); g_strcanon(rtpe_config.software_id, "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890-", '-'); diff --git a/daemon/rtpengine.pod b/daemon/rtpengine.pod index 30c34737d..0249f0803 100644 --- a/daemon/rtpengine.pod +++ b/daemon/rtpengine.pod @@ -833,6 +833,18 @@ If any CN parameters are configured, the parameters will be passed to an RFC 3389 CN decoder, and the generated comfort noise will be used to fill in DTX gaps. +=item B<--amr-dtx=>B|B + +Select the DTX behaviour for AMR codecs. The default is use the codec's +internal processing: during a DTX event, a "no data" frame is passed to the +decoder and the output is used as audio data. + +If B is selected here, the same DTX mechanism as other codecs use is used +for AMR, which is to fill in DTX gaps with either silence or RFC 3389 comfort +noise (see B). This also affects processing of received SID +frames: SID frames would not be passed to the codec but instead be replaced by +generated silence or comfort noise. + =item B<--silence-detect=>I Enable silence detection and specify threshold in percent. This option is diff --git a/include/main.h b/include/main.h index ffb1b1c14..051a016ca 100644 --- a/include/main.h +++ b/include/main.h @@ -117,6 +117,7 @@ struct rtpengine_config { int dtx_lag; int dtx_shift; str dtx_cn_params; + int amr_cn_dtx; double silence_detect_double; uint32_t silence_detect_int; str cn_payload; diff --git a/lib/codeclib.c b/lib/codeclib.c index ebe949994..c45c9829a 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -112,14 +112,17 @@ static const codec_type_t codec_type_cn = { }; static const dtx_method_t dtx_method_silence = { + .method_id = DTX_SILENCE, .do_dtx = generic_silence_dtx, }; static const dtx_method_t dtx_method_cn = { + .method_id = DTX_CN, .do_dtx = generic_cn_dtx, .init = generic_cn_dtx_init, .cleanup = generic_cn_dtx_cleanup, }; static const dtx_method_t dtx_method_amr = { + .method_id = DTX_NATIVE, .do_dtx = amr_dtx, }; @@ -472,6 +475,7 @@ static codec_def_t __codec_defs[] = { .codec_type = &codec_type_amr, .set_enc_options = amr_set_enc_options, .set_dec_options = amr_set_dec_options, + .amr = 1, .dtx_methods = { [DTX_NATIVE] = &dtx_method_amr, [DTX_SILENCE] = &dtx_method_silence, @@ -494,6 +498,7 @@ static codec_def_t __codec_defs[] = { .codec_type = &codec_type_amr, .set_enc_options = amr_set_enc_options, .set_dec_options = amr_set_dec_options, + .amr = 1, .dtx_methods = { [DTX_NATIVE] = &dtx_method_amr, [DTX_SILENCE] = &dtx_method_silence, @@ -2097,8 +2102,22 @@ static int amr_decoder_input(decoder_t *dec, const str *data, GQueue *out) { } err = "failed to decode AMR data"; - if (avc_decoder_input(dec, &frame, out)) - goto err; + if (bits == 40) { + // SID + if (dec->dtx.method_id == DTX_NATIVE) { + if (avc_decoder_input(dec, &frame, out)) + goto err; + } + else { + // use the DTX generator to replace SID + if (dec->dtx.do_dtx(dec, out, 20)) + goto err; + } + } + else { + if (avc_decoder_input(dec, &frame, out)) + goto err; + } amr_bitrate_tracker(dec, ft); } diff --git a/lib/codeclib.h b/lib/codeclib.h index d34e06e91..b6b87bb36 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -156,7 +156,8 @@ struct codec_def_s { // flags unsigned int supplemental:1, - dtmf:1; // special case + dtmf:1, // special case + amr:1; const codec_type_t *codec_type; @@ -181,6 +182,8 @@ enum codec_event { }; struct dtx_method_s { + enum dtx_method method_id; + int (*init)(decoder_t *); void (*cleanup)(decoder_t *); int (*do_dtx)(decoder_t *, GQueue *, int);