FS-4037 --resolve
This commit is contained in:
parent
f209ae0191
commit
4817768299
|
@ -117,51 +117,143 @@ struct speex_context {
|
|||
|
||||
static switch_status_t switch_speex_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
|
||||
{
|
||||
if (codec_fmtp) {
|
||||
speex_codec_settings_t *codec_settings = NULL;
|
||||
if (codec_fmtp->private_info) {
|
||||
codec_settings = codec_fmtp->private_info;
|
||||
memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings));
|
||||
}
|
||||
speex_codec_settings_t *codec_settings = NULL;
|
||||
int x, argc;
|
||||
char *argv[10];
|
||||
char *fmtp_dup = NULL;
|
||||
|
||||
if (fmtp) {
|
||||
int x, argc;
|
||||
char *argv[10];
|
||||
char *fmtp_dup = strdup(fmtp);
|
||||
|
||||
switch_assert(fmtp_dup);
|
||||
|
||||
argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
||||
for (x = 0; x < argc; x++) {
|
||||
char *data = argv[x];
|
||||
char *arg;
|
||||
switch_assert(data);
|
||||
while (*data == ' ') {
|
||||
data++;
|
||||
}
|
||||
if ((arg = strchr(data, '='))) {
|
||||
*arg++ = '\0';
|
||||
/*
|
||||
if (!strcasecmp(data, "bitrate")) {
|
||||
bit_rate = atoi(arg);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (codec_settings) {
|
||||
if (!strcasecmp(data, "vad")) {
|
||||
bit_rate = atoi(arg);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
free(fmtp_dup);
|
||||
}
|
||||
/*codec_fmtp->bits_per_second = bit_rate;*/
|
||||
if (!codec_fmtp) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (!fmtp) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
||||
/* load default settings */
|
||||
if (codec_fmtp->private_info) {
|
||||
codec_settings = codec_fmtp->private_info;
|
||||
memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings));
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "codec_fmtp->private_info is NULL\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got fmtp: %s\n", fmtp);
|
||||
|
||||
fmtp_dup = strdup(fmtp);
|
||||
switch_assert(fmtp_dup);
|
||||
|
||||
/* parse ; separated fmtp args */
|
||||
argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
for (x = 0; x < argc; x++) {
|
||||
char *data = argv[x];
|
||||
char *arg;
|
||||
switch_assert(data);
|
||||
while (*data == ' ') {
|
||||
data++;
|
||||
}
|
||||
if (!(arg = strchr(data, '='))) {
|
||||
continue;
|
||||
}
|
||||
*arg++ = '\0';
|
||||
if (zstr(arg)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcasecmp("vbr", data)) {
|
||||
/* vbr can be on/off/vad */
|
||||
if (!strcasecmp("vad", arg)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "enabling speex vbr=vad\n");
|
||||
codec_settings->vbr = 0;
|
||||
codec_settings->vad = 1;
|
||||
codec_settings->pp_vad = 1;
|
||||
} else {
|
||||
if (switch_true(arg)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "enabling speex vbr\n");
|
||||
codec_settings->vbr = 1;
|
||||
codec_settings->vad = 0;
|
||||
codec_settings->pp_vad = 1;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "disabling speex vbr\n");
|
||||
codec_settings->vbr = 0;
|
||||
codec_settings->vad = 0;
|
||||
codec_settings->pp_vad = 0;
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp("cng", data)) {
|
||||
/* TODO don't know how to turn on CNG */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "speex cng is unsupported\n");
|
||||
} else if (!strcasecmp("mode", data)) {
|
||||
/* mode is a comma-separate list of preferred modes. Use the first mode in the list */
|
||||
char *arg_dup;
|
||||
char *mode[2];
|
||||
if (!strncasecmp("any", arg, 3)) {
|
||||
/* "any", keep the default setting */
|
||||
continue;
|
||||
}
|
||||
arg_dup = strdup(arg);
|
||||
if (switch_separate_string(arg_dup, ',', mode, (sizeof(mode) / sizeof(mode[0])))) {
|
||||
int mode_num = -1;
|
||||
char *mode_str = mode[0];
|
||||
if (mode_str[0] == '"') {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "mode starts with \"\n");
|
||||
mode_str++;
|
||||
}
|
||||
if (switch_is_number(mode_str)) {
|
||||
mode_num = atoi(mode_str);
|
||||
}
|
||||
/* TODO there might be a way to set the mode directly instead of changing the quality */
|
||||
if (codec_fmtp->actual_samples_per_second == 8000) {
|
||||
switch (mode_num) {
|
||||
case 1:
|
||||
codec_settings->quality = 0;
|
||||
break;
|
||||
case 2:
|
||||
codec_settings->quality = 2;
|
||||
break;
|
||||
case 3:
|
||||
codec_settings->quality = 4;
|
||||
break;
|
||||
case 4:
|
||||
codec_settings->quality = 6;
|
||||
break;
|
||||
case 5:
|
||||
codec_settings->quality = 8;
|
||||
break;
|
||||
case 6:
|
||||
codec_settings->quality = 9;
|
||||
break;
|
||||
case 7:
|
||||
codec_settings->quality = 10;
|
||||
break;
|
||||
case 8:
|
||||
codec_settings->quality = 1;
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ignoring invalid speex/8000 mode %s\n", mode_str);
|
||||
continue;
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "choosing speex/8000 mode %s\n", mode_str);
|
||||
codec_settings->quality = codec_settings->quality;
|
||||
codec_settings->vbr_quality = codec_settings->quality;
|
||||
} else {
|
||||
if (mode_num >= 0 && mode_num <= 10) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "choosing speex/%d mode %s\n", codec_fmtp->actual_samples_per_second, mode_str);
|
||||
codec_settings->quality = mode_num;
|
||||
codec_settings->vbr_quality = mode_num;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ignoring invalid speex/%d mode %s\n", codec_fmtp->actual_samples_per_second, mode_str);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(arg_dup);
|
||||
}
|
||||
}
|
||||
free(fmtp_dup);
|
||||
/*codec_fmtp->bits_per_second = bit_rate;*/
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,6 +274,7 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla
|
|||
|
||||
memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
|
||||
codec_fmtp.private_info = &codec_settings;
|
||||
codec_fmtp.actual_samples_per_second = codec->implementation->actual_samples_per_second;
|
||||
switch_speex_fmtp_parse(codec->fmtp_in, &codec_fmtp);
|
||||
|
||||
memcpy(&context->codec_settings, &codec_settings, sizeof(context->codec_settings));
|
||||
|
@ -205,11 +298,24 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla
|
|||
speex_encoder_ctl(context->encoder_state, SPEEX_GET_FRAME_SIZE, &context->encoder_frame_size);
|
||||
speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &context->codec_settings.complexity);
|
||||
if (context->codec_settings.preproc) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor on\n");
|
||||
context->pp = speex_preprocess_state_init(context->encoder_frame_size, codec->implementation->actual_samples_per_second);
|
||||
if (context->codec_settings.pp_vad) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor vad on\n");
|
||||
}
|
||||
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &context->codec_settings.pp_vad);
|
||||
if (context->codec_settings.pp_agc) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor agc on\n");
|
||||
}
|
||||
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &context->codec_settings.pp_agc);
|
||||
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &context->codec_settings.pp_agc_level);
|
||||
if (context->codec_settings.pp_denoise) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor denoise on\n");
|
||||
}
|
||||
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &context->codec_settings.pp_denoise);
|
||||
if (context->codec_settings.pp_dereverb) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor dereverb on\n");
|
||||
}
|
||||
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &context->codec_settings.pp_dereverb);
|
||||
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &context->codec_settings.pp_dereverb_decay);
|
||||
speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &context->codec_settings.pp_dereverb_level);
|
||||
|
@ -218,17 +324,21 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla
|
|||
if (!context->codec_settings.abr && !context->codec_settings.vbr) {
|
||||
speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &context->codec_settings.quality);
|
||||
if (context->codec_settings.vad) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "vad on\n");
|
||||
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &context->codec_settings.vad);
|
||||
}
|
||||
}
|
||||
if (context->codec_settings.vbr) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "vbr on\n");
|
||||
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &context->codec_settings.vbr);
|
||||
speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &context->codec_settings.vbr_quality);
|
||||
}
|
||||
if (context->codec_settings.abr) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "abr on\n");
|
||||
speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &context->codec_settings.abr);
|
||||
}
|
||||
if (context->codec_settings.dtx) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "dtx on\n");
|
||||
speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &context->codec_settings.dtx);
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +353,7 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla
|
|||
|
||||
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "initialized Speex codec \n");
|
||||
codec->private_info = context;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -279,17 +390,15 @@ static switch_status_t switch_speex_encode(switch_codec_t *codec,
|
|||
|
||||
if (is_speech) {
|
||||
switch_clear_flag(context, SWITCH_CODEC_FLAG_SILENCE);
|
||||
*flag |= SWITCH_CODEC_FLAG_SILENCE_STOP;
|
||||
*flag &= ~SFF_CNG;
|
||||
} else {
|
||||
if (switch_test_flag(context, SWITCH_CODEC_FLAG_SILENCE)) {
|
||||
*encoded_data_len = 0;
|
||||
*flag |= SWITCH_CODEC_FLAG_SILENCE | SFF_CNG;
|
||||
*flag |= SFF_CNG;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_set_flag(context, SWITCH_CODEC_FLAG_SILENCE);
|
||||
*flag |= SWITCH_CODEC_FLAG_SILENCE_START;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue