Browse Source

TT#122401 add configurable CN method

Change-Id: I2aa9901b2a9dcf64563a84d77fa40d23b6c25525
rfuchs/1283
Richard Fuchs 5 years ago
parent
commit
ec68dfeb31
6 changed files with 71 additions and 29 deletions
  1. +2
    -0
      daemon/codec.c
  2. +32
    -20
      daemon/main.c
  3. +24
    -7
      daemon/rtpengine.pod
  4. +1
    -0
      include/main.h
  5. +10
    -2
      lib/codeclib.c
  6. +2
    -0
      lib/codeclib.h

+ 2
- 0
daemon/codec.c View File

@ -2835,6 +2835,8 @@ 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);
ch->decoder->event_data = h->media;
ch->decoder->event_func = codec_decoder_event;


+ 32
- 20
daemon/main.c View File

@ -363,6 +363,32 @@ static int redis_ep_parse(endpoint_t *ep, int *db, char **auth, const char *auth
}
static void parse_cn_payload(str *out, char **in, const char *def, const char *name) {
if (!in || !*in) {
if (def)
str_init_dup(out, def);
return;
}
int len = g_strv_length(in);
if (len < 1)
die("Invalid CN payload specified (--%s)", name);
out->s = malloc(len);
for (int i = 0; i < len; i++) {
char *endp;
long p = strtol(in[i], &endp, 0);
if (endp == in[i] || *endp != '\0')
die("Invalid CN payload specified (--%s)", name);
if (p < 0 || p > 254)
die("Invalid CN payload specified (--%s)", name);
if (i == 0 && p > 127)
die("Invalid CN payload specified (--%s)", name);
out->s[i] = p;
}
out->len = len;
}
static void options(int *argc, char ***argv) {
AUTO_CLEANUP_GVBUF(if_a);
@ -395,6 +421,7 @@ static void options(int *argc, char ***argv) {
AUTO_CLEANUP_GBUF(dtls_sig);
double silence_detect = 0;
AUTO_CLEANUP_GVBUF(cn_payload);
AUTO_CLEANUP_GVBUF(dtx_cn_params);
int debug_srtp = 0;
rwlock_lock_w(&rtpe_config.config_lock);
@ -494,6 +521,7 @@ static void options(int *argc, char ***argv) {
{ "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-cn-params",0,0, G_OPTION_ARG_STRING_ARRAY,&dtx_cn_params, "Parameters for CN generated from DTX","INT INT INT ..."},
{ "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},
@ -737,26 +765,8 @@ static void options(int *argc, char ***argv) {
rtpe_config.silence_detect_int = (int) ((silence_detect / 100.0) * UINT32_MAX);
}
if (!cn_payload)
str_init_dup(&rtpe_config.cn_payload, "\x20");
else {
int len = g_strv_length(cn_payload);
if (len < 1)
die("Invalid CN payload specified");
rtpe_config.cn_payload.s = malloc(len);
for (int i = 0; i < len; i++) {
char *endp;
long p = strtol(cn_payload[i], &endp, 0);
if (endp == cn_payload[i] || *endp != '\0')
die("Invalid CN payload specified");
if (p < 0 || p > 254)
die("Invalid CN payload specified");
if (i == 0 && p > 127)
die("Invalid CN payload specified");
rtpe_config.cn_payload.s[i] = p;
}
rtpe_config.cn_payload.len = len;
}
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 (!rtpe_config.software_id)
rtpe_config.software_id = g_strdup_printf("rtpengine-%s", RTPENGINE_VERSION);
@ -895,6 +905,8 @@ static void options_free(void) {
g_free(rtpe_config.software_id);
if (rtpe_config.cn_payload.s)
free(rtpe_config.cn_payload.s);
if (rtpe_config.dtx_cn_params.s)
free(rtpe_config.dtx_cn_params.s);
// free common config options
config_load_free(&rtpe_config.common);


+ 24
- 7
daemon/rtpengine.pod View File

@ -785,13 +785,13 @@ non-alphanumeric characters with a dash to make it universally usable.
=item B<--dtx-delay=>I<INT>
Processing delay in milliseconds to handle discontinuous transmission (DTX) or
other transmission gaps for codecs that support it (currently only AMR and
AMR-WB). Defaults to zero (disabled) and applicable to transcoded audio streams
only. When enabled, delays processing of received packets for the specified
time (much like a jitter buffer) in order to trigger DTX handling when a
transmission gap occurs. The decoder is then instructed to fill in the missing
time during a transmission gap, for example by generating comfort noise. The
delay should be configured to be higher than the expected incoming jitter.
other transmission gaps. Defaults to zero (disabled) and is applicable to
transcoded audio streams only. When enabled, delays processing of received
packets for the specified time (much like a jitter buffer) in order to trigger
DTX handling when a transmission gap occurs. The decoder is then instructed to
fill in the missing time during a transmission gap, for example by generating
comfort noise. The delay should be configured to be higher than the expected
incoming jitter.
=item B<--max-dtx=>I<INT>
@ -820,6 +820,19 @@ or backwards (delayed) in case of a DTX buffer overflow or underflow. An
underflow occurs when RTP packets are received slower than expected, while an
overflow occurs when packets are received faster than expected.
=item B<--dtx-cn-params=>I<INT>
Specify one comfort noise parameter. This option follows the same format as
B<cn-payload> described below.
This option is applicable to audio generated to fill in transmission gaps
during a DTX event. The default setting is no value, which means silence will
be generated to fill in DTX gaps.
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<--silence-detect=>I<FLOAT>
Enable silence detection and specify threshold in percent. This option is
@ -862,6 +875,10 @@ coefficients) as per RFC 3389. Allowable values for each coefficient are
between 0 and 254. Specifying spectral information is optional and the number
of coefficients listed (model order) is variable.
This option is applicable only to B<CN> packets generated from the silence
detection mechanism described above. The configured CN parameters are used
directly as payload of B<CN> packets sent by B<rtpengine>.
The default values are 32 (-32 dBov) for the noise level and no spectral
information.


+ 1
- 0
include/main.h View File

@ -116,6 +116,7 @@ struct rtpengine_config {
int dtx_buffer;
int dtx_lag;
int dtx_shift;
str dtx_cn_params;
double silence_detect_double;
uint32_t silence_detect_int;
str cn_payload;


+ 10
- 2
lib/codeclib.c View File

@ -697,6 +697,13 @@ int decoder_switch_dtx(decoder_t *dec, enum dtx_method dm) {
return 0;
}
int decoder_set_cn_dtx(decoder_t *dec, const str *cn_pl) {
if (decoder_switch_dtx(dec, DTX_CN))
return -1;
dec->dtx.u.cn.cn_payload = cn_pl;
return 0;
}
gboolean decoder_has_dtx(decoder_t *dec) {
return dec->dtx.do_dtx == NULL ? FALSE : TRUE;
@ -2317,8 +2324,9 @@ static int cn_append_frame(decoder_t *dec, AVFrame *f, void *u1, void *u2) {
}
static int generic_cn_dtx(decoder_t *dec, GQueue *out, int ptime) {
static const str cn_pl = { "\x10", 1 };
return decoder_input_data(dec->dtx.u.cn.cn_dec, &cn_pl, dec->rtp_ts, cn_append_frame, out, NULL);
dec->dtx.u.cn.cn_dec->ptime = ptime;
return decoder_input_data(dec->dtx.u.cn.cn_dec, dec->dtx.u.cn.cn_payload,
dec->rtp_ts, cn_append_frame, out, NULL);
}
static int generic_cn_dtx_init(decoder_t *dec) {


+ 2
- 0
lib/codeclib.h View File

@ -188,6 +188,7 @@ struct dtx_method_s {
union {
struct {
decoder_t *cn_dec;
const str *cn_payload;
} cn;
} u;
};
@ -305,6 +306,7 @@ int decoder_input_data(decoder_t *dec, const str *data, unsigned long ts,
int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2);
gboolean decoder_has_dtx(decoder_t *);
int decoder_switch_dtx(decoder_t *dec, enum dtx_method);
int decoder_set_cn_dtx(decoder_t *dec, const str *);
int decoder_dtx(decoder_t *dec, unsigned long ts, int ptime,
int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2);


Loading…
Cancel
Save