From a1d2158b6f4b4e47bc185e73624c8087d4562a97 Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Fri, 27 Apr 2007 18:47:43 +0000 Subject: [PATCH] codec order priority patch ba juha. git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@315 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- core/AmConfig.cpp | 7 +++++-- core/AmConfig.h | 1 + core/AmPlugIn.cpp | 18 ++++++++++++++-- core/AmPlugIn.h | 3 +++ core/AmSdp.cpp | 30 ++++++++++++++------------ core/AmUtils.cpp | 49 ++++++++++++++++++++++++++++--------------- core/AmUtils.h | 5 +++++ core/sems.conf.sample | 10 +++++++++ 8 files changed, 89 insertions(+), 34 deletions(-) diff --git a/core/AmConfig.cpp b/core/AmConfig.cpp index 0547bf47..2678bfc5 100644 --- a/core/AmConfig.cpp +++ b/core/AmConfig.cpp @@ -35,6 +35,7 @@ #include "sems.h" #include "log.h" #include "AmConfigReader.h" +#include "AmUtils.h" string AmConfig::ConfigurationFile = CONFIG_FILE; string AmConfig::ModConfigPath = MOD_CFG_PATH; @@ -57,6 +58,7 @@ string AmConfig::LocalSIPIP = ""; string AmConfig::Signature = ""; bool AmConfig::SingleCodecInOK = false; unsigned int AmConfig::DeadRtpTime = DEAD_RTP_TIME; +vector AmConfig::CodecOrder; AmSessionTimerConfig AmConfig::defaultSessionTimerConfig; @@ -247,11 +249,14 @@ int AmConfig::readConfiguration() return -1; } } + // single codec in 200 OK if(cfg.hasParameter("single_codec_in_ok")){ SingleCodecInOK = (cfg.getParameter("single_codec_in_ok") == "yes"); } + // codec_order + CodecOrder = explode(cfg.getParameter("codec_order"), ","); // dead_rtp_time if(cfg.hasParameter("dead_rtp_time")){ @@ -337,5 +342,3 @@ int AmSessionTimerConfig::setMinimumTimer(const string& minse) { return 1; } /* end Session Timer: -ssa */ - - diff --git a/core/AmConfig.h b/core/AmConfig.h index 0ca74cf5..e912f0db 100644 --- a/core/AmConfig.h +++ b/core/AmConfig.h @@ -87,6 +87,7 @@ struct AmConfig static string Signature; /** If 200 OK reply should be limited to preferred codec only */ static bool SingleCodecInOK; + static vector CodecOrder; /** Time of no RTP after which Session is regarded as dead, 0 for no Timeout */ static unsigned int DeadRtpTime; diff --git a/core/AmPlugIn.cpp b/core/AmPlugIn.cpp index d9cb363d..03aecb8b 100644 --- a/core/AmPlugIn.cpp +++ b/core/AmPlugIn.cpp @@ -502,6 +502,7 @@ int AmPlugIn::addCodec(amci_codec_t* c) int AmPlugIn::addPayload(amci_payload_t* p) { amci_codec_t* c; + unsigned int i, id; if( !(c = codec(p->codec_id)) ){ ERROR("in payload '%s': codec id (%i) not supported\n",p->name,p->codec_id); return -1; @@ -512,14 +513,27 @@ int AmPlugIn::addPayload(amci_payload_t* p) return -1; } payloads.insert(std::make_pair(p->payload_id,p)); - DBG("payload '%s'inserted with id %i \n",p->name,p->payload_id); + id = p->payload_id; } else { payloads.insert(std::make_pair(dynamic_pl,p)); - DBG("payload '%s'inserted with id %i \n",p->name,dynamic_pl); + id = dynamic_pl; dynamic_pl++; } + for (i = 0; i < AmConfig::CodecOrder.size(); i++) { + if (p->name == AmConfig::CodecOrder[i]) break; + } + if (i >= AmConfig::CodecOrder.size()) { + payload_order.insert(std::make_pair(id + 100, id)); + DBG("payload '%s' inserted with id %i and order %i\n", + p->name, id, id + 100); + } else { + payload_order.insert(std::make_pair(i, id)); + DBG("payload '%s' inserted with id %i and order %i\n", + p->name, id, i); + } + return 0; } diff --git a/core/AmPlugIn.h b/core/AmPlugIn.h index 3612cbde..6370f219 100644 --- a/core/AmPlugIn.h +++ b/core/AmPlugIn.h @@ -66,6 +66,7 @@ class AmPlugIn map codecs; map payloads; + map payload_order; map file_formats; map name2app; @@ -108,6 +109,8 @@ class AmPlugIn amci_payload_t* payload(int payload_id); /** @return the suported payloads. */ const map& getPayloads() { return payloads; } + /** @return the order of payloads. */ + const map& getPayloadOrder() { return payload_order; } /** * File format lookup according to the * format name and/or file extension. diff --git a/core/AmSdp.cpp b/core/AmSdp.cpp index 789bf691..a55590cc 100644 --- a/core/AmSdp.cpp +++ b/core/AmSdp.cpp @@ -245,7 +245,8 @@ int AmSdp::genRequest(const string& localip,int localport, string& out_buf) { AmPlugIn* plugin = AmPlugIn::instance(); const map& payloads = plugin->getPayloads(); - + const map& payload_order = plugin->getPayloadOrder(); + if(payloads.empty()){ ERROR("no payload plugin loaded.\n"); return -1; @@ -266,22 +267,25 @@ int AmSdp::genRequest(const string& localip,int localport, string& out_buf) "t=0 0\r\n" "m=audio " + int2str(localport) + " RTP/AVP "; - map::const_iterator it = payloads.begin(); - out_buf += int2str((it++)->first); + map::const_iterator it = payload_order.begin(); + out_buf += int2str((it++)->second); - for(;it != payloads.end();++it) - out_buf += string(" ") + int2str(it->first); + for(; it != payload_order.end(); ++it) + out_buf += string(" ") + int2str(it->second); out_buf += "\r\n"; - for(it = payloads.begin();it != payloads.end();++it) { - - //if(it->first >= 96) { - out_buf += "a=rtpmap:" + int2str(it->first) - + " " + string(it->second->name) - + "/" + int2str(it->second->sample_rate) - + "\r\n"; - //} + for (it = payload_order.begin(); it != payload_order.end(); ++it) { + map::const_iterator it2 = payloads.find(it->second); + if (it2 != payloads.end()) { + out_buf += "a=rtpmap:" + int2str(it2->first) + + " " + string(it2->second->name) + + "/" + int2str(it2->second->sample_rate) + + "\r\n"; + } else { + ERROR("Payload %d was not found in payloads map!\n", it->second); + return -1; + } } return 0; diff --git a/core/AmUtils.cpp b/core/AmUtils.cpp index 96baac9c..4f28fab7 100644 --- a/core/AmUtils.cpp +++ b/core/AmUtils.cpp @@ -841,6 +841,21 @@ unsigned int get_random() return r; } +// Explode string by a separator to a vector +vector explode(string s, string e) { + vector ret; + int iPos = s.find(e, 0); + int iLen = e.length(); + while (iPos > -1) { + if (iPos != 0) + ret.push_back(s.substr(0, iPos)); + s.erase(0, iPos+iLen); + iPos = s.find(e, 0); + } + if (s != "") + ret.push_back(s); + return ret; +} // Warning: static var is not mutexed @@ -848,29 +863,29 @@ unsigned int get_random() // void add_env_path(const char* name, const string& path) { - string var(path); - char* old_path=0; + string var(path); + char* old_path=0; - regex_t path_reg; + regex_t path_reg; - assert(name); - if((old_path = getenv(name)) != 0) { - if(strlen(old_path)){ + assert(name); + if((old_path = getenv(name)) != 0) { + if(strlen(old_path)){ - if(regcomp(&path_reg,("[:|^]" + path + "[:|$]").c_str(),REG_NOSUB)){ - ERROR("could not compile regex\n"); - return; - } + if(regcomp(&path_reg,("[:|^]" + path + "[:|$]").c_str(),REG_NOSUB)){ + ERROR("could not compile regex\n"); + return; + } - if(!regexec(&path_reg,old_path,0,0,0)) { // match + if(!regexec(&path_reg,old_path,0,0,0)) { // match - return; // do nothing - } + return; // do nothing + } - var += ":" + string(old_path); - } + var += ":" + string(old_path); } + } - DBG("setting %s to: '%s'\n",name,var.c_str()); - setenv("PYTHONPATH",var.c_str(),1); + DBG("setting %s to: '%s'\n",name,var.c_str()); + setenv("PYTHONPATH",var.c_str(),1); } diff --git a/core/AmUtils.h b/core/AmUtils.h index c4af9f56..6c07ae2a 100644 --- a/core/AmUtils.h +++ b/core/AmUtils.h @@ -35,6 +35,8 @@ #include using std::string; +#include + #define FIFO_PERM S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH #define PARAM_HDR "P-App-Param" @@ -263,6 +265,9 @@ string get_session_param(const string& hdrs, const string& name); void init_random(); unsigned int get_random(); +// Explode string by a separator to a vector +std::vector explode(string s, string e); + // add a directory to an environement variable void add_env_path(const char* name, const string& path); diff --git a/core/sems.conf.sample b/core/sems.conf.sample index 19bfd33f..54a87ceb 100644 --- a/core/sems.conf.sample +++ b/core/sems.conf.sample @@ -165,3 +165,13 @@ media_processor_threads=1 # default=no # # single_codec_in_ok=no + +# optional parameter: codec_order=codec_name_1,codec_name2,... +# +# - Codec order used when sending INVITE requests. Codecs in codec_order +# will be on the top of the list followed by other supported codecs +# (if any). +# +# default=empty +# +# codec_order=iLBC,GSM