Commit 64bf85eb authored by Rafaël Carré's avatar Rafaël Carré
Browse files

* #6905 : fix AudioCodecFactory access in optimized builds (-O > 0)

refactor while we're at it
parent cac23d80
......@@ -94,7 +94,7 @@ void Account::setActiveCodecs (const std::vector <std::string> &list)
for (std::vector<std::string>::const_iterator iter = list.begin(); iter != list.end();
++iter) {
int payload = std::atoi (iter->c_str());
codecOrder_.push_back ( (AudioCodecType) payload);
codecOrder_.push_back ( (int) payload);
}
// update the codec string according to new codec selection
......
......@@ -36,8 +36,7 @@
#include <algorithm> // for std::find
#include "fileutils.h"
void
AudioCodecFactory::init()
AudioCodecFactory::AudioCodecFactory() : codecsMap_()
{
typedef std::vector<sfl::Codec*> CodecVector;
CodecVector codecDynamicList(scanCodecDirectory());
......@@ -46,7 +45,7 @@ AudioCodecFactory::init()
else {
for (CodecVector::const_iterator iter = codecDynamicList.begin();
iter != codecDynamicList.end() ; ++iter) {
codecsMap_[ (AudioCodecType) (*iter)->getPayloadType() ] = *iter;
codecsMap_[ (int) (*iter)->getPayloadType() ] = *iter;
_debug ("Loaded codec %s" , (*iter)->getMimeSubtype().c_str());
}
}
......@@ -61,7 +60,7 @@ void AudioCodecFactory::setDefaultOrder()
}
std::string
AudioCodecFactory::getCodecName (AudioCodecType payload)
AudioCodecFactory::getCodecName (int payload) const
{
CodecsMap::const_iterator iter = codecsMap_.find (payload);
......@@ -71,8 +70,20 @@ AudioCodecFactory::getCodecName (AudioCodecType payload)
return "";
}
std::vector<int32_t >
AudioCodecFactory::getAudioCodecList() const
{
std::vector<int32_t> list;
for (CodecsMap::const_iterator iter = codecsMap_.begin(); iter != codecsMap_.end(); ++iter)
if (iter->second)
list.push_back((int32_t)iter->first);
return list;
}
sfl::Codec*
AudioCodecFactory::getCodec (AudioCodecType payload)
AudioCodecFactory::getCodec (int payload) const
{
CodecsMap::const_iterator iter = codecsMap_.find (payload);
......@@ -84,7 +95,7 @@ AudioCodecFactory::getCodec (AudioCodecType payload)
}
}
double AudioCodecFactory::getBitRate (AudioCodecType payload)
double AudioCodecFactory::getBitRate (int payload) const
{
CodecsMap::const_iterator iter = codecsMap_.find (payload);
......@@ -95,7 +106,7 @@ double AudioCodecFactory::getBitRate (AudioCodecType payload)
}
int AudioCodecFactory::getSampleRate (AudioCodecType payload) const
int AudioCodecFactory::getSampleRate (int payload) const
{
CodecsMap::const_iterator iter = codecsMap_.find (payload);
......@@ -114,18 +125,16 @@ void AudioCodecFactory::saveActiveCodecs (const std::vector<std::string>& list)
for (std::vector<std::string>::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
int payload = std::atoi(iter->c_str());
if (isCodecLoaded (payload))
defaultCodecOrder_.push_back ( (AudioCodecType) payload);
defaultCodecOrder_.push_back ( (int) payload);
}
}
void
AudioCodecFactory::deleteHandlePointer()
AudioCodecFactory::~AudioCodecFactory()
{
for (std::vector<CodecHandlePointer>::const_iterator iter =
codecInMemory_.begin(); iter != codecInMemory_.end(); ++iter)
unloadCodec (*iter);
codecInMemory_.clear();
}
std::vector<sfl::Codec*> AudioCodecFactory::scanCodecDirectory()
......@@ -211,9 +220,9 @@ void AudioCodecFactory::unloadCodec (CodecHandlePointer p)
dlclose (p.second);
}
sfl::Codec* AudioCodecFactory::instantiateCodec (AudioCodecType payload)
sfl::Codec* AudioCodecFactory::instantiateCodec (int payload) const
{
std::vector< CodecHandlePointer >::iterator iter;
std::vector< CodecHandlePointer >::const_iterator iter;
for (iter = codecInMemory_.begin(); iter != codecInMemory_.end(); ++iter) {
if (iter->first->getPayloadType() == payload) {
......@@ -275,7 +284,7 @@ AudioCodecFactory::alreadyInCache (const std::string &lib)
return std::find(libCache_.begin(), libCache_.end(), lib) != libCache_.end();
}
bool AudioCodecFactory::isCodecLoaded (int payload)
bool AudioCodecFactory::isCodecLoaded (int payload) const
{
CodecsMap::const_iterator iter;
for (iter = codecsMap_.begin(); iter != codecsMap_.end(); ++iter)
......@@ -285,21 +294,21 @@ bool AudioCodecFactory::isCodecLoaded (int payload)
return false;
}
std::vector <std::string> AudioCodecFactory::getCodecSpecifications (const int32_t& payload)
std::vector <std::string> AudioCodecFactory::getCodecSpecifications (const int32_t& payload) const
{
std::vector<std::string> v;
std::stringstream ss;
// Add the name of the codec
v.push_back(getCodecName(static_cast<AudioCodecType>(payload)));
v.push_back(getCodecName(static_cast<int>(payload)));
// Add the sample rate
ss << getSampleRate (static_cast<AudioCodecType>(payload));
ss << getSampleRate (static_cast<int>(payload));
v.push_back(ss.str());
ss.str("");
// Add the bit rate
ss << getBitRate(static_cast<AudioCodecType>(payload));
ss << getBitRate(static_cast<int>(payload));
v.push_back(ss.str());
return v;
......
......@@ -46,18 +46,14 @@
*/
/** Maps a pointer on an audiocodec object to a payload */
typedef std::map<AudioCodecType, sfl::Codec*> CodecsMap;
typedef std::map<int, sfl::Codec*> CodecsMap;
class AudioCodecFactory
{
public:
/**
* Accessor to data structures
* @return CodecsMap& The available codec
*/
const CodecsMap& getCodecsMap() const {
return codecsMap_;
}
AudioCodecFactory();
~AudioCodecFactory();
/**
* Get codec name by its payload
......@@ -65,19 +61,15 @@ class AudioCodecFactory
* same as getPayload()
* @return std::string The name of the codec
*/
std::string getCodecName (AudioCodecType payload);
std::string getCodecName (int payload) const;
std::vector<int32_t > getAudioCodecList() const;
/**
* Get the codec object associated with the payload
* @param payload The payload looked for
* @return AudioCodec* A pointer on a AudioCodec object
*/
sfl::Codec* getCodec (AudioCodecType payload);
/**
* Initialiaze the map with all the supported codecs, even those inactive
*/
void init();
sfl::Codec* getCodec (int payload) const;
/**
* Set the default codecs order.
......@@ -90,14 +82,14 @@ class AudioCodecFactory
* @param payload The payload of the codec
* @return double The bit rate
*/
double getBitRate (AudioCodecType payload);
double getBitRate (int payload) const;
/**
* Get the clock rate of the specified codec
* @param payload The payload of the codec
* @return int The clock rate of the specified codec
*/
int getSampleRate (AudioCodecType payload) const;
int getSampleRate (int payload) const;
/**
* Set the order of codecs by their payload
......@@ -105,16 +97,11 @@ class AudioCodecFactory
*/
void saveActiveCodecs (const std::vector<std::string>& list);
/**
* Unreferences the codecs loaded in memory
*/
void deleteHandlePointer (void);
/**
* Instantiate a codec, used in AudioRTP to get an instance of Codec per call
* @param CodecHandlePointer The map containing the pointer on the object and the pointer on the handle function
*/
sfl::Codec* instantiateCodec (AudioCodecType payload);
sfl::Codec* instantiateCodec (int payload) const;
/**
* For a given codec, return its specification
......@@ -122,7 +109,7 @@ class AudioCodecFactory
* @param payload The RTP payload of the codec
* @return std::vector <std::string> A vector containing codec's name, sample rate, bandwidth and bit rate
*/
std::vector <std::string> getCodecSpecifications (const int32_t& payload);
std::vector <std::string> getCodecSpecifications (const int32_t& payload) const;
/**
* Check if the audiocodec object has been successfully created
......@@ -130,7 +117,7 @@ class AudioCodecFactory
* @return bool True if the audiocodec has been created
* false otherwise
*/
bool isCodecLoaded (int payload);
bool isCodecLoaded (int payload) const;
private:
/** Enable us to keep the handle pointer on the codec dynamicaly loaded so that we could destroy when we dont need it anymore */
......
......@@ -285,7 +285,7 @@
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
<arg type="as" name="list" direction="out">
<arg type="ai" name="list" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
......
......@@ -160,18 +160,9 @@ std::vector<std::string> ConfigurationManager::getAccountList()
* Send the list of all codecs loaded to the client through DBus.
* Can stay global, as only the active codecs will be set per accounts
*/
std::vector<std::string> ConfigurationManager::getAudioCodecList (void)
std::vector<int32_t > ConfigurationManager::getAudioCodecList (void)
{
std::vector<std::string> list;
const CodecsMap &codecs(Manager::instance().getAudioCodecFactory().getCodecsMap());
for (CodecsMap::const_iterator iter = codecs.begin(); iter != codecs.end(); ++iter)
if (iter->second) {
std::stringstream ss;
ss << iter->first;
list.push_back (ss.str());
}
std::vector<int32_t> list(Manager::instance().audioCodecFactory.getAudioCodecList());
if (list.empty())
errorAlert(CODECS_NOT_LOADED);
......@@ -192,7 +183,7 @@ std::vector<std::string> ConfigurationManager::getSupportedTlsMethod (void)
std::vector<std::string> ConfigurationManager::getAudioCodecDetails (const int32_t& payload)
{
std::vector<std::string> result(Manager::instance().getAudioCodecFactory().getCodecSpecifications(payload));
std::vector<std::string> result(Manager::instance().audioCodecFactory.getCodecSpecifications(payload));
if (result.empty())
errorAlert(CODECS_NOT_LOADED);
return result;
......
......@@ -69,7 +69,7 @@ class ConfigurationManager
std::map< std::string, std::string > getTlsSettingsDefault (void);
std::vector< std::string > getAudioCodecList (void);
std::vector< int32_t > getAudioCodecList (void);
std::vector< std::string > getSupportedTlsMethod (void);
std::vector< std::string > getAudioCodecDetails (const int32_t& payload);
std::vector< std::string > getActiveAudioCodecList (const std::string& accountID);
......
......@@ -130,7 +130,7 @@ static const SOUND_FORMAT INT32 = 0x8;
#define HOOK_DEFAULT_URL_COMMAND "x-www-browser"
/** Enumeration that contains known audio payloads */
typedef enum {
enum {
// http://www.iana.org/assignments/rtp-parameters
// http://www.gnu.org/software/ccrtp/doc/refman/html/formats_8h.html#a0
// 0 PCMU A 8000 1 [RFC3551]
......@@ -152,10 +152,10 @@ typedef enum {
PAYLOAD_CODEC_SPEEX_8000 = 110,
PAYLOAD_CODEC_SPEEX_16000 = 111,
PAYLOAD_CODEC_SPEEX_32000 = 112
} AudioCodecType;
};
/** The struct to reflect the order the user wants to use the codecs */
typedef std::vector<AudioCodecType> CodecOrder;
typedef std::vector<int> CodecOrder;
#define IP2IP_PROFILE "IP2IP"
#define DIR_SEPARATOR_STR "/" // Directory separator char
......
......@@ -35,9 +35,9 @@
#include "manager.h"
namespace {
int codecToASTFormat(AudioCodecType c)
int codecToASTFormat(int c)
{
static std::map<AudioCodecType, int> mapping;
static std::map<int, int> mapping;
if (mapping.empty()) {
mapping[PAYLOAD_CODEC_ULAW] = AST_FORMAT_ULAW;
mapping[PAYLOAD_CODEC_GSM] = AST_FORMAT_GSM;
......@@ -53,9 +53,9 @@ namespace {
else
return mapping[c];
}
AudioCodecType ASTFormatToCodec(int format)
int ASTFormatToCodec(int format)
{
static std::map<int, AudioCodecType> mapping;
static std::map<int, int> mapping;
if (mapping.empty()) {
mapping[AST_FORMAT_ULAW] = PAYLOAD_CODEC_ULAW;
mapping[AST_FORMAT_GSM] = PAYLOAD_CODEC_GSM;
......@@ -65,7 +65,7 @@ namespace {
}
if (mapping.find(format) == mapping.end()) {
_error("Format not supported!");
return static_cast<AudioCodecType>(-1);
return static_cast<int>(-1);
}
else
return mapping[format];
......@@ -118,12 +118,7 @@ int IAXCall::getFirstMatchingFormat (int needles, const std::string &accountID)
return 0;
}
AudioCodecFactory& IAXCall::getAudioCodecFactory()
{
return _audioCodecFactory;
}
AudioCodecType IAXCall::getAudioCodec()
int IAXCall::getAudioCodec()
{
return _audioCodec;
}
......@@ -102,26 +102,11 @@ class IAXCall : public Call
*/
int getFirstMatchingFormat (int needles, const std::string &accountID) const;
// AUDIO
/**
* Set internal codec Map: initialization only, not protected
* @param map The codec map
*/
void setCodecMap (const AudioCodecFactory& factory) {
_audioCodecFactory = factory;
}
/**
* Get internal codec Map: initialization only, not protected
* @return CodecDescriptor The codec map
*/
AudioCodecFactory& getAudioCodecFactory();
/**
* Return audio codec [mutex protected]
* @return AudioCodecType The payload of the codec
* @return int The payload of the codec
*/
AudioCodecType getAudioCodec();
int getAudioCodec();
private:
/** Each call is associated with an iax_session */
......@@ -131,15 +116,12 @@ class IAXCall : public Call
* Set the audio codec used. [not protected]
* @param audioCodec The payload of the codec
*/
void setAudioCodec (AudioCodecType audioCodec) {
void setAudioCodec (int audioCodec) {
_audioCodec = audioCodec;
}
/** Codec Map */
AudioCodecFactory _audioCodecFactory;
/** Codec pointer */
AudioCodecType _audioCodec;
int _audioCodec;
/**
* Format currently in use in the conversation,
......
......@@ -210,8 +210,8 @@ IAXVoIPLink::sendAudioFromMic (void)
if (!currentCall or currentCall->getState() != Call::Active)
continue;
AudioCodecType codecType = currentCall->getAudioCodec();
sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(currentCall->getAudioCodecFactory().getCodec(codecType));
int codecType = currentCall->getAudioCodec();
sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(Manager::instance().audioCodecFactory.getCodec(codecType));
if (!audioCodec or !audiolayer_)
continue;
......@@ -325,7 +325,6 @@ Call*
IAXVoIPLink::newOutgoingCall (const std::string& id, const std::string& toUrl)
{
IAXCall* call = new IAXCall (id, Call::Outgoing);
call->setCodecMap (Manager::instance().getAudioCodecFactory());
call->setPeerNumber (toUrl);
call->initRecFileName (toUrl);
......@@ -347,7 +346,6 @@ void
IAXVoIPLink::answer (Call *c)
{
IAXCall* call = dynamic_cast<IAXCall*>(c);
call->setCodecMap(Manager::instance().getAudioCodecFactory());
Manager::instance().addStream (call->getCallId());
......@@ -513,7 +511,7 @@ std::string
IAXVoIPLink::getCurrentCodecName(Call *c) const
{
IAXCall *call = dynamic_cast<IAXCall*>(c);
sfl::Codec *audioCodec = call->getAudioCodecFactory().getCodec(call->getAudioCodec());
sfl::Codec *audioCodec = Manager::instance().audioCodecFactory.getCodec(call->getAudioCodec());
return audioCodec ? audioCodec->getMimeSubtype() : "";
}
......@@ -690,7 +688,7 @@ IAXVoIPLink::iaxHandleVoiceEvent (iax_event* event, IAXCall* call)
return;
}
sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(call->getAudioCodecFactory().getCodec(call->getAudioCodec()));
sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(Manager::instance().audioCodecFactory.getCodec(call->getAudioCodec()));
if (!audioCodec)
return;
......@@ -813,9 +811,6 @@ IAXVoIPLink::iaxHandlePrecallEvent (iax_event* event)
// Associate the call to the session.
call->setSession (event->session);
// setCallAudioLocal(call);
call->setCodecMap (Manager::instance().getAudioCodecFactory());
call->setConnectionState (Call::Progressing);
......
......@@ -70,7 +70,7 @@
ManagerImpl::ManagerImpl (void) :
_hasTriedToRegister (false), _config(), _currentCallId2(),
_currentCallMutex(), _audiodriver (0),
_dtmfKey (0), _audioCodecFactory(), _toneMutex(),
_dtmfKey (0), _toneMutex(),
_telephoneTone (0), _audiofile (0), _spkr_volume (0),
_mic_volume (0), _waitingCall(),
_waitingCallMutex(), _nbIncomingWaitingCall (0), _path (""),
......@@ -118,9 +118,6 @@ void ManagerImpl::init (std::string config_file)
initVolume();
initAudioDriver();
// Initialize the list of supported audio codecs
_audioCodecFactory.init();
audioLayerMutexLock();
if (_audiodriver) {
......@@ -156,7 +153,6 @@ void ManagerImpl::terminate ()
delete _audiodriver;
_audiodriver = NULL;
_audioCodecFactory.deleteHandlePointer();
audioLayerMutexUnlock();
}
......@@ -1870,7 +1866,7 @@ void ManagerImpl::ringtone (const std::string& accountID)
else {
sfl::Codec *codec;
if (ringchoice.find (".ul") != std::string::npos || ringchoice.find (".au") != std::string::npos)
codec = _audioCodecFactory.getCodec(PAYLOAD_CODEC_ULAW);
codec = audioCodecFactory.getCodec(PAYLOAD_CODEC_ULAW);
else
throw AudioFileException("Couldn't guess an appropriate decoder");
_audiofile = new RawFile(ringchoice, static_cast<sfl::AudioCodec *>(codec), samplerate);
......
......@@ -153,21 +153,13 @@ class ManagerImpl
return _audiodriver;
}
/**
* Get a descriptor map of codec available
* @return CodecDescriptor The internal codec map
*/
AudioCodecFactory& getAudioCodecFactory (void) {
return _audioCodecFactory;
}
/**
* Functions which occur with a user's action
* Place a new call
* @param accountId The account to make tha call with
* @param call_id The call identifier
* @param to The recipient of the call
* @param conf_id The conference identifier if any
* @param conf_id The conference identifier if any
* @return bool true on success
* false otherwise
*/
......@@ -934,6 +926,10 @@ class ManagerImpl
* @return std::vector<std::string> A vector containing the account ID's
*/
std::vector<std::string> loadAccountOrder () const;
// map of codec (for configlist request)
const AudioCodecFactory audioCodecFactory;
private:
/**
* Play the dtmf-associated sound
......@@ -995,9 +991,6 @@ class ManagerImpl
DTMF* _dtmfKey;
// map of codec (for configlist request)
AudioCodecFactory _audioCodecFactory;
/////////////////////
// Protected by Mutex
/////////////////////
......
......@@ -77,7 +77,6 @@ void Sdp::setActiveLocalSdpSession (const pjmedia_sdp_session *sdp)
pjmedia_sdp_media *current;
sdpMedia *media = NULL;
std::string dir;
CodecsMap codecs_list;
pjmedia_sdp_attr *attribute = NULL;
pjmedia_sdp_rtpmap *rtpmap;
......@@ -85,8 +84,6 @@ void Sdp::setActiveLocalSdpSession (const pjmedia_sdp_session *sdp)
activeLocalSession_ = (pjmedia_sdp_session*) sdp;
codecs_list = Manager::instance().getAudioCodecFactory().getCodecsMap();
// retrieve the media information
nb_media = activeLocalSession_->media_count;
......@@ -111,15 +108,15 @@ void Sdp::setActiveLocalSdpSession (const pjmedia_sdp_session *sdp)
pjmedia_sdp_attr_to_rtpmap (memPool_, attribute, &rtpmap);
CodecsMap::iterator iter = codecs_list.find ( (AudioCodecType) pj_strtoul (&rtpmap->pt));
sfl::Codec *codec = Manager::instance().audioCodecFactory.getCodec((int) pj_strtoul (&rtpmap->pt));
if (iter == codecs_list.end())
if (!codec)
{
delete media;
return;
}
media->add_codec (iter->second);
media->add_codec(codec);
}
sessionAudioMedia_.push_back (media);
......@@ -286,17 +283,13 @@ void Sdp::setLocalMediaCapabilities (const CodecOrder &selectedCodecs)
audio = new sdpMedia (MIME_TYPE_AUDIO);
audio->set_port (getLocalPublishedAudioPort());
/* We retrieve the codecs selected by the user */
CodecsMap codecs_list = Manager::instance().getAudioCodecFactory().getCodecsMap();
if (selectedCodecs.size() == 0)
_warn("No selected codec while building local SDP offer");
else {
for (CodecOrder::const_iterator iter = selectedCodecs.begin(); iter != selectedCodecs.end(); ++iter) {
CodecsMap::const_iterator map_iter = codecs_list.find (*iter);
if (map_iter != codecs_list.end())
audio->add_codec (map_iter->second);
sfl::Codec *codec = Manager::instance().audioCodecFactory.getCodec(*iter);
if (codec)
audio->add_codec(codec);
else
_warn ("SDP: Couldn't find audio codec");
}
......
......@@ -573,7 +573,7 @@ Call *SIPVoIPLink::newOutgoingCall (const std::string& id, const std::string& to
// Initialize the session using ULAW as default codec in case of early media
// The session should be ready to receive media once the first INVITE is sent, before
// the session initialization is completed
sfl::Codec* audiocodec = Manager::instance().getAudioCodecFactory().instantiateCodec (PAYLOAD_CODEC_ULAW);
sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec (PAYLOAD_CODEC_ULAW);
if (audiocodec == NULL) {
_error ("UserAgent: Could not instantiate codec");
delete call;
......@@ -763,20 +763,20 @@ SIPVoIPLink::offhold (const std::string& id)
try {
// Retreive previously selected codec
AudioCodecType pl;
int pl;
sfl::Codec *sessionMedia = sdpSession->getSessionMedia();
if (sessionMedia == NULL) {
_warn("UserAgent: Session media not yet initialized, using default (ULAW)");
pl = PAYLOAD_CODEC_ULAW;