From 36b5a5de821e1f48daaf7fea25dad545c04dff61 Mon Sep 17 00:00:00 2001 From: Emmanuel Milou <emmanuel.milou@savoirfairelinux.comemmanuel.milou@savoirfairelinux.com> Date: Fri, 25 Jan 2008 13:58:18 -0500 Subject: [PATCH] Improve IAX dynamic codec loading --- src/audio/audiortp.cpp | 3 +- src/audio/codecDescriptor.cpp | 16 ++++--- src/audio/codecDescriptor.h | 25 ++++++++--- src/iaxcall.cpp | 1 - src/iaxvoiplink.cpp | 85 +++++++++++++++-------------------- src/iaxvoiplink.h | 6 +++ src/managerimpl.cpp | 11 ----- src/sipcall.cpp | 4 +- 8 files changed, 73 insertions(+), 78 deletions(-) diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index f91414d530..e4b16cbdfa 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -260,8 +260,7 @@ AudioRtpRTX::loadCodec(int payload) { using std::cout; using std::cerr; - void* codec; - + void* codec; switch(payload){ case 0: diff --git a/src/audio/codecDescriptor.cpp b/src/audio/codecDescriptor.cpp index 92cf39c6aa..1c066f867d 100644 --- a/src/audio/codecDescriptor.cpp +++ b/src/audio/codecDescriptor.cpp @@ -53,7 +53,7 @@ CodecDescriptor::getCodecName(CodecType payload) } bool -CodecDescriptor::setActive(CodecType payload) +CodecDescriptor::isSupported(CodecType payload) { CodecMap::iterator iter = _codecMap.begin(); while(iter!=_codecMap.end()) { @@ -65,19 +65,17 @@ CodecDescriptor::setActive(CodecType payload) } iter++; } - - ///TODO: add the codec in the activ codecs list return false; } void -CodecDescriptor::setInactive(CodecType payload) +CodecDescriptor::removeCodec(CodecType payload) { CodecMap::iterator iter = _codecMap.begin(); while(iter!=_codecMap.end()) { if (iter->first == payload) { - ///TODO : erase the codec from the list () - //iter->second->setActive(false); + _debug("Codec %s removed from the list", getCodecName(payload).data()); + _codecMap.erase(iter); break; } iter++; @@ -85,3 +83,9 @@ CodecDescriptor::setInactive(CodecType payload) } +void +CodecDescriptor::addCodec(CodecType payload) +{ +} + + diff --git a/src/audio/codecDescriptor.h b/src/audio/codecDescriptor.h index 193ea88933..22c920cf26 100644 --- a/src/audio/codecDescriptor.h +++ b/src/audio/codecDescriptor.h @@ -69,14 +69,25 @@ public: std::string& getCodecName(CodecType payload); /** - * Put a codec active, with its codec's _description - * O(n) if not found where n is the number of element - * @param codecDescription is the same as with getCodec(number)->getDescription() + * Check in the map codec if the specified codec is supported + * @param payload unique identifier of a codec (RFC) + * @return true if the codec specified is supported + * false otherwise */ - //void setActive(const std::string& codecName); - bool setActive(CodecType payload); - //void setInactive(const std::string& codecName); - void setInactive(CodecType payload); + bool isSupported(CodecType payload); + + /** + * Remove the codec with payload payload from the list + * @param payload the codec to erase + */ + void removeCodec(CodecType payload); + + /** + * Add a codec in the list + * @param payload the codec to add + */ + void addCodec(CodecType payload); + private: CodecMap _codecMap; }; diff --git a/src/iaxcall.cpp b/src/iaxcall.cpp index a2c07838f5..7a58d91caa 100644 --- a/src/iaxcall.cpp +++ b/src/iaxcall.cpp @@ -34,7 +34,6 @@ void IAXCall::setFormat(int format) { _format = format; - switch(format) { /*case AST_FORMAT_ULAW: setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ULAW)); break; diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp index fa77f7ce95..de824d06d9 100644 --- a/src/iaxvoiplink.cpp +++ b/src/iaxvoiplink.cpp @@ -228,39 +228,50 @@ IAXVoIPLink::getEvent() _evThread->sleep(3); } - -void -IAXVoIPLink::sendAudioFromMic(void) +AudioCodec* +IAXVoIPLink::loadCodec(int payload) { - - IAXCall* currentCall = getIAXCall(Manager::instance().getCurrentCallId()); - //CodecType audiocodec = (CodecType) -1; - using std::cout; using std::cerr; - void* codec = dlopen("codec_alaw.so", RTLD_LAZY); - if(!codec){ + void* handle_codec; + + switch(payload) + { + case 0: + handle_codec = dlopen("codec_ulaw.so", RTLD_LAZY); + break; + case 3: + handle_codec = dlopen("codec_gsm.so", RTLD_LAZY); + break; + case 8: + handle_codec = dlopen("codec_alaw.so", RTLD_LAZY); + break; + } + if(!handle_codec){ cerr<<"cannot load library: "<< dlerror() <<'\n'; } + // reset errors + dlerror(); -//reset errors - dlerror(); - -//load the symbols - create_t* create_codec = (create_t*)dlsym(codec, "create"); + // load the symbols + create_t* create_codec = (create_t*)dlsym(handle_codec, "create"); const char* dlsym_error = dlerror(); if(dlsym_error){ - cerr << "Cannot load symbol create: " << dlsym_error << '\n'; + cerr << "Cannot load symbol create: " << dlsym_error << '\n'; } - destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy"); + destroy_t* destroy_codec = (destroy_t*) dlsym(handle_codec, "destroy"); dlsym_error = dlerror(); if(dlsym_error){ cerr << "Cannot load symbol destroy" << dlsym_error << '\n'; } + return create_codec(); +} - - AudioCodec* audiocodec = create_codec(); - +void +IAXVoIPLink::sendAudioFromMic(void) +{ + + IAXCall* currentCall = getIAXCall(Manager::instance().getCurrentCallId()); if (!currentCall) { // Let's mind our own business. @@ -277,8 +288,7 @@ IAXVoIPLink::sendAudioFromMic(void) return; } - //audiocodec = currentCall->getAudioCodec(); - + AudioCodec* audiocodec = loadCodec(currentCall->getAudioCodec()); if (!audiocodec) { // Audio codec still not determined. if (audiolayer) { @@ -395,8 +405,8 @@ IAXVoIPLink::sendAudioFromMic(void) _mutexIAX.leaveMutex(); } - destroy_codec(audiocodec); - dlclose(codec); + //destroy_codec(audiocodec); + //dlclose(codec); } @@ -786,40 +796,17 @@ IAXVoIPLink::iaxHandleVoiceEvent(iax_event* event, IAXCall* call) //_debug("IAX: Skipping empty jitter-buffer interpolated packet\n"); return; } - - using std::cout; -using std::cerr; -void* codec = dlopen("codec_alaw.so", RTLD_LAZY); -if(!codec){ - cerr<<"cannot load library: "<< dlerror() <<'\n'; -} - -//reset errors -dlerror(); -create_t* create_codec = (create_t*)dlsym(codec, "create"); -const char* dlsym_error = dlerror(); -if(dlsym_error){ - cerr << "Cannot load symbol create: " << dlsym_error << '\n'; -} -destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy"); -dlsym_error = dlerror(); -if(dlsym_error){ - cerr << "Cannot load symbol destroy" << dlsym_error << '\n'; -} AudioCodec* audiocodec; if (audiolayer) { - //AudioCodec* audiocodec = call->getAudioCodec(); - audiocodec = create_codec(); // On-the-fly codec changing (normally, when we receive a full packet) // as per http://tools.ietf.org/id/draft-guy-iax-03.txt // - subclass holds the voiceformat property. if (event->subclass && event->subclass != call->getFormat()) { call->setFormat(event->subclass); - //audiocodec = call->getAudioCodec(); } - + audiocodec = loadCodec(call->getAudioCodec()); //_debug("Receive: len=%d, format=%d, _receiveDataDecoded=%p\n", event->datalen, call->getFormat(), _receiveDataDecoded); unsigned char* data = (unsigned char*)event->data; @@ -880,8 +867,8 @@ AudioCodec* audiocodec; } else { _debug("IAX: incoming audio, but no sound card open"); } -destroy_codec(audiocodec); -dlclose(codec); +//destroy_codec(audiocodec); +//dlclose(codec); } diff --git a/src/iaxvoiplink.h b/src/iaxvoiplink.h index b0f5ea17a4..02e910c342 100644 --- a/src/iaxvoiplink.h +++ b/src/iaxvoiplink.h @@ -152,6 +152,12 @@ private: */ int iaxCodecMapToFormat(IAXCall* call); + /** + * Dynamically load an audio codec + * @return audiocodec a pointer on an audiocodec object + */ + AudioCodec* loadCodec(int payload); + /** Threading object */ EventThread* _evThread; diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 7887e499db..e2446b543b 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -1087,12 +1087,6 @@ void ManagerImpl::initAudioCodec (void) { _debugInit("Active Codecs"); - //_codecDescriptorMap.setActive(getConfigString("Audio", "Codecs.codec1")); - //_codecDescriptorMap.setActive(getConfigString("Audio", "Codec.codec2")); - //_codecDescriptorMap.setActive(getConfigString("Audio", "Codec.codec3")); - //_codecDescriptorMap.setActive("G711a"); - //_codecDescriptorMap.setActive("G711u"); - //_codecDescriptorMap.setActive("GSM"); } void @@ -1106,11 +1100,6 @@ ManagerImpl::setPreferedCodec(const ::DBus::String& codec_name) tmp = list[0]; list[0] = list[i]; list[i] = tmp; - //_codecDescriptorMap.setActive(list[0]); - //_codecDescriptorMap.setInactive(list[1]); - //_codecDescriptorMap.setInactive(list[2]); - //_codecDescriptorMap.setActive(list[1]); - //_codecDescriptorMap.setActive(list[2]); setConfig("Audio", "Codecs.codec1", list[0]); setConfig("Audio", "Codecs.codec2", list[1]); setConfig("Audio", "Codecs.codec3", list[2]); diff --git a/src/sipcall.cpp b/src/sipcall.cpp index 3bbb6f361d..0b01f94626 100644 --- a/src/sipcall.cpp +++ b/src/sipcall.cpp @@ -360,7 +360,7 @@ SIPCall::sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg) _debug("remote payload = %s\n", tmp); CodecType audiocodec = (CodecType)payload; //if (audiocodec != NULL && audiocodec->isActive()) { - if (audiocodec != (CodecType)-1 && _codecMap.setActive(audiocodec)) { //TODO: check if the remote payload matches with one of the codec map + if (audiocodec != (CodecType)-1 && _codecMap.isSupported(audiocodec)) { listCodec << payload << " "; //listRtpMap << "a=rtpmap:" << payload << " " << audiocodec->getCodecName() << "/" << audiocodec->getClockRate(); listRtpMap << "a=rtpmap:" << payload << " " << _codecMap.getCodecName(audiocodec) << "/" << 8000; @@ -586,7 +586,7 @@ SIPCall::setAudioCodecFromSDP(sdp_media_t* remote_med, int tid) if (tmp != NULL ) { int payload = atoi(tmp); // stop if we find a correct codec - if (_codecMap.setActive((CodecType)payload)){ + if (_codecMap.isSupported((CodecType)payload)){ break; } } -- GitLab