From 0ed9ebe492d970086158865902b74081e46b1f75 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 28 Jan 2007 17:37:51 +0000 Subject: [PATCH] CODEC TWEAK mod_sofia will now examine a variable in the channel to see what the channel's originator was using for a codec and try to put that to the top of the list in the sdp. if this new sofia profile param is set: All outbound calls will use *only* the codec that thier originator is using to ensure no transcoding. (of course that could lead to a failed call where there is no way to do this, so use sparingly) git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4073 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- conf/sofia.conf.xml | 4 ++- src/include/switch_types.h | 1 + src/include/switch_utils.h | 5 ++++ src/mod/endpoints/mod_sofia/mod_sofia.c | 37 +++++++++++++++++++++---- src/switch_core.c | 13 +++++++-- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/conf/sofia.conf.xml b/conf/sofia.conf.xml index 675ad86583..4d4f4fd53b 100644 --- a/conf/sofia.conf.xml +++ b/conf/sofia.conf.xml @@ -38,7 +38,9 @@ - + + diff --git a/src/include/switch_types.h b/src/include/switch_types.h index da384d4741..7921e6bad0 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -82,6 +82,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_BRIDGE_VARIABLE "_bridge_to_" #define SWITCH_SIGNAL_BRIDGE_VARIABLE "_signal_bridge_to_" #define SWITCH_ORIGINATOR_VARIABLE "_originator_" +#define SWITCH_ORIGINATOR_CODEC_VARIABLE "_originator_codec_" #define SWITCH_LOCAL_MEDIA_IP_VARIABLE "_local_media_ip_" #define SWITCH_LOCAL_MEDIA_PORT_VARIABLE "_local_media_port_" #define SWITCH_REMOTE_MEDIA_IP_VARIABLE "_remote_media_ip_" diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 569ba1a023..9242b8ef59 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -62,6 +62,11 @@ SWITCH_DECLARE(apr_status_t) switch_socket_recvfrom(apr_sockaddr_t *from, apr_so apr_size_t *len); +#define switch_codec2str(codec,buf,len) snprintf(buf, len, "%s@%uk@%ui", \ + codec->implementation->iananame, \ + codec->implementation->samples_per_second, \ + codec->implementation->microseconds_per_frame / 1000) + #ifdef WIN32 #define switch_is_file_path(file) (*(file +1) == ':' || *file == '/') #else diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index c17e1b6fbe..0ddbaca63e 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -142,7 +142,8 @@ typedef enum { PFLAG_AUTH_ALL = (1 << 2), PFLAG_FULL_ID = (1 << 3), PFLAG_PRESENCE = (1 << 4), - PFLAG_PASS_RFC2833 = (1 << 5) + PFLAG_PASS_RFC2833 = (1 << 5), + PFLAG_DISABLE_TRANSCODING = (1 << 6) } PFLAGS; typedef enum { @@ -772,6 +773,8 @@ static void tech_set_codecs(private_object_t *tech_pvt) { switch_channel_t *channel; char *codec_string = NULL; + char *csdyn = NULL; + char *ocodec = NULL; if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) { return; @@ -786,11 +789,25 @@ static void tech_set_codecs(private_object_t *tech_pvt) channel = switch_core_session_get_channel(tech_pvt->session); assert (channel != NULL); + if (!(codec_string = switch_channel_get_variable(channel, "codec_string"))) { codec_string = tech_pvt->profile->codec_string; } + if ((ocodec = switch_channel_get_variable(channel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) { + if (!codec_string || (tech_pvt->profile->pflags & PFLAG_DISABLE_TRANSCODING)) { + codec_string = ocodec; + } else { + if ((csdyn = switch_mprintf("%s,%s", ocodec, codec_string))) { + codec_string = csdyn; + } else { + codec_string = ocodec; + } + } + } + if (codec_string) { + tech_pvt->profile->codec_order_last = switch_separate_string(codec_string, ',', tech_pvt->profile->codec_order, SWITCH_MAX_CODECS); tech_pvt->num_codecs = switch_loadable_module_get_codecs_sorted(tech_pvt->codecs, SWITCH_MAX_CODECS, tech_pvt->profile->codec_order, @@ -800,6 +817,8 @@ static void tech_set_codecs(private_object_t *tech_pvt) tech_pvt->num_codecs = switch_loadable_module_get_codecs(switch_core_session_get_pool(tech_pvt->session), tech_pvt->codecs, sizeof(tech_pvt->codecs) / sizeof(tech_pvt->codecs[0])); } + + switch_safe_free(csdyn); } @@ -829,9 +848,10 @@ static void attach_private(switch_core_session_t *session, switch_core_session_set_private(session, tech_pvt); - tech_set_codecs(tech_pvt); + snprintf(name, sizeof(name), "sofia/%s/%s", profile->name, channame); switch_channel_set_name(channel, name); + //tech_set_codecs(tech_pvt); } @@ -939,7 +959,8 @@ static void do_invite(switch_core_session_t *session) cid_name = (char *) caller_profile->caller_id_name; cid_num = (char *) caller_profile->caller_id_number; - + tech_set_codecs(tech_pvt); + if ((tech_pvt->from_str = switch_mprintf("\"%s\" ", cid_name, cid_num, @@ -1433,7 +1454,7 @@ static switch_status_t activate_rtp(private_object_t *tech_pvt) flags |= SWITCH_RTP_FLAG_BUGGY_2833; } - if (tech_pvt->profile->flags & PFLAG_PASS_RFC2833 || ((val = switch_channel_get_variable(channel, "pass_rfc2833")) && switch_true(val))) { + if ((tech_pvt->profile->pflags & PFLAG_PASS_RFC2833) || ((val = switch_channel_get_variable(channel, "pass_rfc2833")) && switch_true(val))) { flags |= SWITCH_RTP_FLAG_PASS_RFC2833; } @@ -2205,6 +2226,7 @@ static switch_status_t sofia_outgoing_channel(switch_core_session_t *session, sw attach_private(nsession, profile, tech_pvt, dest); + nchannel = switch_core_session_get_channel(nsession); caller_profile = switch_caller_profile_clone(nsession, outbound_profile); switch_channel_set_caller_profile(nchannel, caller_profile); @@ -4164,7 +4186,7 @@ static void sip_i_invite(nua_t *nua, } attach_private(session, profile, tech_pvt, username); - + tech_set_codecs(tech_pvt); channel = switch_core_session_get_channel(session); switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL"); @@ -4993,6 +5015,10 @@ static switch_status_t config_sofia(int reload) if (switch_true(val)) { profile->pflags |= PFLAG_PASS_RFC2833; } + } else if (!strcasecmp(var, "disable-transcoding")) { + if (switch_true(val)) { + profile->pflags |= PFLAG_DISABLE_TRANSCODING; + } } else if (!strcasecmp(var, "auth-calls")) { if (switch_true(val)) { profile->pflags |= PFLAG_AUTH_CALLS; @@ -5035,7 +5061,6 @@ static switch_status_t config_sofia(int reload) profile->max_calls = atoi(val); } else if (!strcasecmp(var, "codec-prefs")) { profile->codec_string = switch_core_strdup(profile->pool, val); - profile->codec_order_last = switch_separate_string(profile->codec_string, ',', profile->codec_order, SWITCH_MAX_CODECS); } else if (!strcasecmp(var, "codec-ms")) { profile->codec_ms = atoi(val); } else if (!strcasecmp(var, "dtmf-duration")) { diff --git a/src/switch_core.c b/src/switch_core.c index 39148abe25..35e1b4a18f 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1577,10 +1577,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_outgoing_channel(switch_core if (channel && peer_channel) { char *export_vars, *val; + switch_codec_t *read_codec = switch_core_session_get_read_codec(session); - switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_VARIABLE, switch_core_session_get_uuid(session)); - - /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */ + if (read_codec) { + char tmp[80]; + switch_codec2str(read_codec, tmp, sizeof(tmp)); + switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_CODEC_VARIABLE, tmp); + } + + switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_VARIABLE, switch_core_session_get_uuid(session)); + + /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */ if ((export_vars = switch_channel_get_variable(channel, "export_vars"))) { char *cptmp = switch_core_session_strdup(session, export_vars); int argc;