From e83c6a46079f1ef2a34ddc5b66636405e5c77c97 Mon Sep 17 00:00:00 2001 From: jay98237438 <58031260+jay98237438@users.noreply.github.com> Date: Thu, 21 Nov 2019 13:40:56 +0100 Subject: [PATCH 1/2] [mod_amr] RFC4867 mode-set compliancy Yield to offered mode-set when set. From RFC4867: If a mode set was supplied in the offer, the answerer SHALL return the mode-set unmodified or reject the payload type. --- src/mod/codecs/mod_amr/mod_amr.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/mod/codecs/mod_amr/mod_amr.c b/src/mod/codecs/mod_amr/mod_amr.c index 5f18feab7c..4e31522bdb 100644 --- a/src/mod/codecs/mod_amr/mod_amr.c +++ b/src/mod/codecs/mod_amr/mod_amr.c @@ -243,7 +243,7 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ switch_codec_fmtp_t codec_fmtp; amr_codec_settings_t amr_codec_settings = { 0 }; int encoding, decoding; - int x, i, argc; + int x, i, argc, fmtptmp_pos; char *argv[10]; char fmtptmp[128]; @@ -329,25 +329,38 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ if (context->enc_modes) { /* choose the highest mode (bitrate) for high audio quality */ - for (i = 7; i > -1; i--) { + for (i = SWITCH_AMR_MODES-2; i > -1; i--) { if (context->enc_modes & (1 << i)) { context->enc_mode = (switch_byte_t) i; break; } } + + /* re-create mode-set */ + fmtptmp_pos = switch_snprintf(fmtptmp, sizeof(fmtptmp), "mode-set="); + for (i = 0; SWITCH_AMR_MODES-1 > i; ++i) { + if (context->enc_modes & (1 << i)) { + fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, fmtptmp_pos > strlen("mode-set=") ? ",%d" : "%d", i); + } + } + + } else { + /* use default mode-set */ + fmtptmp_pos = switch_snprintf(fmtptmp, sizeof(fmtptmp), "mode-set=%d", context->enc_mode); } if (globals.adjust_bitrate) { switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_ADJ_BITRATE); } + + if (!globals.volte) { - switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d", switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, - context->enc_mode); + fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d", switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0); } else { /* some UEs reject the call with 488 if mode-change-capability is not 2 */ - switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d; max-red=0; mode-change-capability=2", - switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, context->enc_mode); + fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d;max-red=0;mode-change-capability=2", + switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0); } codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp); From f7a424a263680ddcfd974548a61668779e093759 Mon Sep 17 00:00:00 2001 From: jay98237438 <58031260+jay98237438@users.noreply.github.com> Date: Thu, 21 Nov 2019 13:42:54 +0100 Subject: [PATCH 2/2] [mod_amrwb] RFC4867 mode-set compliancy Yield to offered mode-set when set. From RFC4867: If a mode set was supplied in the offer, the answerer SHALL return the mode-set unmodified or reject the payload type. --- src/mod/codecs/mod_amrwb/mod_amrwb.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/mod/codecs/mod_amrwb/mod_amrwb.c b/src/mod/codecs/mod_amrwb/mod_amrwb.c index 19cde02adf..89402dd807 100644 --- a/src/mod/codecs/mod_amrwb/mod_amrwb.c +++ b/src/mod/codecs/mod_amrwb/mod_amrwb.c @@ -189,7 +189,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla #else struct amrwb_context *context = NULL; int encoding, decoding; - int x, i, argc; + int x, i, argc, fmtptmp_pos; char *argv[10]; char fmtptmp[128]; @@ -266,12 +266,24 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla if (context->enc_modes) { /* choose the highest mode (bitrate) for high audio quality. */ - for (i = 8; i > -1; i--) { + for (i = SWITCH_AMRWB_MODES-2; i > -1; i--) { if (context->enc_modes & (1 << i)) { context->enc_mode = (switch_byte_t) i; break; } } + + /* re-create mode-set */ + fmtptmp_pos = switch_snprintf(fmtptmp, sizeof(fmtptmp), "mode-set="); + for (i = 0; SWITCH_AMRWB_MODES-1 > i; ++i) { + if (context->enc_modes & (1 << i)) { + fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, fmtptmp_pos > strlen("mode-set=") ? ",%d" : "%d", i); + } + } + + } else { + /* use default mode-set */ + fmtptmp_pos = switch_snprintf(fmtptmp, sizeof(fmtptmp), "mode-set=%d", context->enc_mode); } if (globals.adjust_bitrate) { @@ -279,11 +291,11 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } if (!globals.volte) { - switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d", - switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, context->enc_mode); + fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d", + switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0); } else { - switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d; max-red=0; mode-change-capability=2", - switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, context->enc_mode); + fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d;max-red=0;mode-change-capability=2", + switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0); } codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp);