diff --git a/daemon/src/audio/audiortp/audio_rtp_factory.cpp b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
index 25be68841ed4df731a051fa92600d9b994347924..246aa520027ee83c3f410f7adb68aec05c3d1a10 100644
--- a/daemon/src/audio/audiortp/audio_rtp_factory.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
@@ -120,12 +120,12 @@ void AudioRtpFactory::initSession()
         rtpSession_ = new AudioSymmetricRtpSession(*ca_);
 }
 
-void sfl::AudioRtpFactory::start(AudioCodec* audiocodec)
+void sfl::AudioRtpFactory::start(const std::vector<AudioCodec*> &audioCodecs)
 {
     if (rtpSession_ == NULL)
         throw AudioRtpFactoryException("RTP session was null when trying to start audio thread");
 
-    if (rtpSession_->startRtpThread(*audiocodec) != 0)
+    if (rtpSession_->startRtpThread(audioCodecs) != 0)
         throw AudioRtpFactoryException("Failed to start AudioRtpSession thread");
 }
 
@@ -145,12 +145,12 @@ int AudioRtpFactory::getSessionMedia()
     return rtpSession_->getCodecPayloadType();
 }
 
-void AudioRtpFactory::updateSessionMedia(AudioCodec *audiocodec)
+void AudioRtpFactory::updateSessionMedia(const std::vector<AudioCodec*> &audioCodecs)
 {
     if (rtpSession_ == NULL)
         throw AudioRtpFactoryException("rtpSession_ was NULL when trying to update IP address");
 
-    rtpSession_->updateSessionMedia(*audiocodec);
+    rtpSession_->updateSessionMedia(audioCodecs);
 }
 
 void AudioRtpFactory::updateDestinationIpAddress()
diff --git a/daemon/src/audio/audiortp/audio_rtp_factory.h b/daemon/src/audio/audiortp/audio_rtp_factory.h
index 96cdca10fa26672ee630162f7ec1f260259f55d0..8a74067b9559ad44d4e69b96da57f6ab5b090b60 100644
--- a/daemon/src/audio/audiortp/audio_rtp_factory.h
+++ b/daemon/src/audio/audiortp/audio_rtp_factory.h
@@ -81,7 +81,7 @@ class AudioRtpFactory {
          * file. initAudioSymmetricRtpSession must have been called prior to that.
          * @param None
          */
-        void start(AudioCodec*);
+        void start(const std::vector<AudioCodec*> &audioCodecs);
 
         /**
          * Stop the audio rtp thread of the type specified in the configuration
@@ -98,7 +98,7 @@ class AudioRtpFactory {
         /**
          * Dynamically update session media
          */
-        void updateSessionMedia(AudioCodec *);
+        void updateSessionMedia(const std::vector<AudioCodec*> &audioCodecs);
 
         /**
          * Update current RTP destination address with one stored in call
diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
index 6e96499c677339a4c45f1bb50299289bd583e558..4ab82a27c286dbc087d1edd85152ade738a2fc66 100644
--- a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
@@ -90,7 +90,7 @@ AudioRtpRecord::AudioRtpRecord() :
       callId_("")
     , codecSampleRate_(0)
     , dtmfQueue_()
-    , audioCodec_(0)
+    , audioCodecs_()
     , audioCodecMutex_()
     , codecPayloadType_(0)
     , hasDynamicPayloadType_(false)
@@ -121,6 +121,14 @@ bool AudioRtpRecord::isDead()
 #endif
 }
 
+void
+AudioRtpRecord::deleteCodecs()
+{
+    for (std::vector<AudioCodec *>::iterator i = audioCodecs_.begin(); i != audioCodecs_.end(); ++i)
+        delete *i;
+    audioCodecs_.clear();
+}
+
 AudioRtpRecord::~AudioRtpRecord()
 {
     dead_ = true;
@@ -135,8 +143,7 @@ AudioRtpRecord::~AudioRtpRecord()
     converterDecode_ = 0;
     {
         ost::MutexLock lock(audioCodecMutex_);
-        delete audioCodec_;
-        audioCodec_ = 0;
+        deleteCodecs();
     }
 #if HAVE_SPEEXDSP
     {
@@ -160,17 +167,17 @@ AudioRtpRecordHandler::AudioRtpRecordHandler(SIPCall &call) :
 
 AudioRtpRecordHandler::~AudioRtpRecordHandler() {}
 
-void AudioRtpRecordHandler::setRtpMedia(AudioCodec *audioCodec)
+void AudioRtpRecordHandler::setRtpMedia(const std::vector<AudioCodec*> &audioCodecs)
 {
     ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_);
 
-    delete audioRtpRecord_.audioCodec_;
+    audioRtpRecord_.deleteCodecs();
     // Set varios codec info to reduce indirection
-    audioRtpRecord_.audioCodec_ = audioCodec;
-    audioRtpRecord_.codecPayloadType_ = audioCodec->getPayloadType();
-    audioRtpRecord_.codecSampleRate_ = audioCodec->getClockRate();
-    audioRtpRecord_.codecFrameSize_ = audioCodec->getFrameSize();
-    audioRtpRecord_.hasDynamicPayloadType_ = audioCodec->hasDynamicPayload();
+    audioRtpRecord_.audioCodecs_ = audioCodecs;
+    audioRtpRecord_.codecPayloadType_ = audioCodecs[0]->getPayloadType();
+    audioRtpRecord_.codecSampleRate_ = audioCodecs[0]->getClockRate();
+    audioRtpRecord_.codecFrameSize_ = audioCodecs[0]->getFrameSize();
+    audioRtpRecord_.hasDynamicPayloadType_ = audioCodecs[0]->hasDynamicPayload();
 }
 
 void AudioRtpRecordHandler::initBuffers()
@@ -266,9 +273,13 @@ int AudioRtpRecordHandler::processDataEncode()
 
     {
         ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_);
-        RETURN_IF_NULL(audioRtpRecord_.audioCodec_, 0, "Audio codec already destroyed");
+        if (audioRtpRecord_.audioCodecs_.empty()) {
+            ERROR("Audio codecs already destroyed");
+            return 0;
+        }
+        RETURN_IF_NULL(audioRtpRecord_.audioCodecs_[0], 0, "Audio codec already destroyed");
         unsigned char *micDataEncoded = audioRtpRecord_.encodedData_.data();
-        return audioRtpRecord_.audioCodec_->encode(micDataEncoded, out, getCodecFrameSize());
+        return audioRtpRecord_.audioCodecs_[0]->encode(micDataEncoded, out, getCodecFrameSize());
     }
 }
 #undef RETURN_IF_NULL
@@ -283,6 +294,7 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si
         if (!warningInterval_) {
             warningInterval_ = 250;
             WARN("Invalid payload type %d, expected %d", payloadType, audioRtpRecord_.codecPayloadType_);
+            WARN("We have %u codecs total", audioRtpRecord_.audioCodecs_.size());
         }
         warningInterval_--;
         return;
@@ -293,9 +305,13 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si
     SFLDataFormat *spkrDataDecoded = audioRtpRecord_.decData_.data();
     {
         ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_);
-        RETURN_IF_NULL(audioRtpRecord_.audioCodec_, "Audio codec already destroyed");
+        if (audioRtpRecord_.audioCodecs_.empty()) {
+            ERROR("Audio codecs already destroyed");
+            return;
+        }
+        RETURN_IF_NULL(audioRtpRecord_.audioCodecs_[0], "Audio codecs already destroyed");
         // Return the size of data in samples
-        inSamples = audioRtpRecord_.audioCodec_->decode(spkrDataDecoded, spkrData, size);
+        inSamples = audioRtpRecord_.audioCodecs_[0]->decode(spkrDataDecoded, spkrData, size);
     }
 
 #if HAVE_SPEEXDSP
diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.h b/daemon/src/audio/audiortp/audio_rtp_record_handler.h
index 175f202c466bd0929c92fb3942a8c16ecd297fc0..2f35664bb2993d3e566f78b9216d9c948e4434d6 100644
--- a/daemon/src/audio/audiortp/audio_rtp_record_handler.h
+++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.h
@@ -72,12 +72,13 @@ class AudioRtpRecord {
     public:
         AudioRtpRecord();
         ~AudioRtpRecord();
+        void deleteCodecs();
         std::string callId_;
         int codecSampleRate_;
         std::list<DTMFEvent> dtmfQueue_;
 
     private:
-        AudioCodec *audioCodec_;
+        std::vector<AudioCodec*> audioCodecs_;
         ost::Mutex audioCodecMutex_;
         int codecPayloadType_;
         bool hasDynamicPayloadType_;
@@ -122,10 +123,10 @@ class AudioRtpRecordHandler {
         /**
          *  Set rtp media for this session
          */
-        void setRtpMedia(AudioCodec* audioCodec);
+        void setRtpMedia(const std::vector<AudioCodec*> &audioCodec);
 
         AudioCodec *getAudioCodec() const {
-            return audioRtpRecord_.audioCodec_;
+            return audioRtpRecord_.audioCodecs_[0];
         }
 
         int getCodecPayloadType() const {
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.cpp b/daemon/src/audio/audiortp/audio_rtp_session.cpp
index 9a960a0b5f11fb208914cc2e0d5f1623af08db3f..a33811f491937d5e0272e172c7e0d1e371316db2 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_session.cpp
@@ -61,11 +61,11 @@ AudioRtpSession::~AudioRtpSession()
     queue_.disableStack();
 }
 
-void AudioRtpSession::updateSessionMedia(AudioCodec &audioCodec)
+void AudioRtpSession::updateSessionMedia(const std::vector<AudioCodec*> &audioCodecs)
 {
     int lastSamplingRate = audioRtpRecord_.codecSampleRate_;
 
-    setSessionMedia(audioCodec);
+    setSessionMedia(audioCodecs);
 
     Manager::instance().audioSamplingRateChanged(audioRtpRecord_.codecSampleRate_);
 
@@ -78,9 +78,9 @@ void AudioRtpSession::updateSessionMedia(AudioCodec &audioCodec)
 #endif
 }
 
-void AudioRtpSession::setSessionMedia(AudioCodec &audioCodec)
+void AudioRtpSession::setSessionMedia(const std::vector<AudioCodec*> &audioCodecs)
 {
-    setRtpMedia(&audioCodec);
+    setRtpMedia(audioCodecs);
 
     // G722 requires timestamp to be incremented at 8kHz
     const ost::PayloadType payloadType = getCodecPayloadType();
@@ -231,7 +231,7 @@ void AudioRtpSession::updateDestinationIpAddress()
 }
 
 
-int AudioRtpSession::startRtpThread(AudioCodec &audiocodec)
+int AudioRtpSession::startRtpThread(const std::vector<AudioCodec*> &audioCodecs)
 {
     if (isStarted_)
         return 0;
@@ -240,7 +240,7 @@ int AudioRtpSession::startRtpThread(AudioCodec &audiocodec)
 
     isStarted_ = true;
     setSessionTimeouts();
-    setSessionMedia(audiocodec);
+    setSessionMedia(audioCodecs);
     initBuffers();
 #if HAVE_SPEEXDSP
     initNoiseSuppress();
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.h b/daemon/src/audio/audiortp/audio_rtp_session.h
index 3b2ab5975a2d521e3a7c0a355d7e00888e4c8166..fdf40d027ee35d672aebcf3f9ef8e3533a1985db 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.h
+++ b/daemon/src/audio/audiortp/audio_rtp_session.h
@@ -57,9 +57,9 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         AudioRtpSession(SIPCall &sipcall, ost::RTPDataQueue &queue, ost::Thread &thread);
         virtual ~AudioRtpSession();
 
-        void updateSessionMedia(AudioCodec &audioCodec);
+        void updateSessionMedia(const std::vector<AudioCodec*> &audioCodecs);
 
-        virtual int startRtpThread(AudioCodec&);
+        virtual int startRtpThread(const std::vector<AudioCodec*> &audioCodecs);
 
         /**
          * Used mostly when receiving a reinvite
@@ -80,7 +80,7 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         /**
          * Set the audio codec for this RTP session
          */
-        void setSessionMedia(AudioCodec &codec);
+        void setSessionMedia(const std::vector<AudioCodec*> &codec);
 
 
         bool onRTPPacketRecv(ost::IncomingRTPPkt&);
diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
index ddf51f96c01af9ba7c9d67dd10f342da6399a90d..8eabee4a3432d0091dbfab906a516a56d242bcd6 100644
--- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
@@ -43,7 +43,7 @@ AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall &call) :
     , ost::SymmetricRTPSession(ost::InetHostAddress(call.getLocalIp().c_str()), call.getLocalAudioPort())
     , AudioRtpSession(call, *this, *this)
     , rtpThread_(*this)
-    , audiocodec_(0)
+    , audioCodecs_()
 {
     DEBUG("Setting new RTP session with destination %s:%d",
             call_.getLocalIp().c_str(), call_.getLocalAudioPort());
@@ -78,14 +78,14 @@ void AudioSymmetricRtpSession::AudioRtpThread::run()
     }
 }
 
-int AudioSymmetricRtpSession::startRtpThread(AudioCodec &audiocodec)
+int AudioSymmetricRtpSession::startRtpThread(const std::vector<AudioCodec*> &audioCodecs)
 {
     DEBUG("Starting main thread");
     if (isStarted_)
         return 0;
 
-    audiocodec_ = &audiocodec;
-    AudioRtpSession::startRtpThread(audiocodec);
+    audioCodecs_ = audioCodecs;
+    AudioRtpSession::startRtpThread(audioCodecs);
     return startSymmetricRtpThread();
 }
 }
diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
index 96c7e9e7d7111d728ac284624e968fdea4ad9983..030440f46d669b87a260685a7d8598c950011ac2 100644
--- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
+++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
@@ -96,10 +96,10 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
                 NON_COPYABLE(AudioRtpThread);
                 AudioSymmetricRtpSession &rtpSession_;
         };
-        int startRtpThread(AudioCodec &audiocodec);
+        int startRtpThread(const std::vector<AudioCodec*> &audioCodecs);
 
         AudioRtpThread   rtpThread_ ;
-        sfl::AudioCodec* audiocodec_;
+        std::vector<sfl::AudioCodec*> audioCodecs_;
 };
 
 }
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.cpp b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
index 722f845022122a3e19287fc8bd2314e987f77256..4e0c584f56ce51b37f1cb33a2a23f6640d152063 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
@@ -150,12 +150,12 @@ int AudioZrtpSession::getIncrementForDTMF() const
     return 160;
 }
 
-int AudioZrtpSession::startRtpThread(AudioCodec &audiocodec)
+int AudioZrtpSession::startRtpThread(const std::vector<AudioCodec*> &audioCodecs)
 {
     if(isStarted_)
         return 0;
 
-    AudioRtpSession::startRtpThread(audiocodec);
+    AudioRtpSession::startRtpThread(audioCodecs);
     return startZrtpThread();
 }
 
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.h b/daemon/src/audio/audiortp/audio_zrtp_session.h
index eea68a0c5d0c322ce4668aad5ec2d33ad87111e5..a4aa98263c54b32b95351230d2c6a38cad9056c8 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.h
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.h
@@ -96,7 +96,7 @@ class AudioZrtpSession :
         void sendMicData();
         void initializeZid();
         std::string zidFilename_;
-        int startRtpThread(AudioCodec &audiocodec);
+        int startRtpThread(const std::vector<AudioCodec*> &audioCodecs);
         virtual int getIncrementForDTMF() const;
 
         AudioZrtpThread rtpThread_;
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index f97b9eabd68a0f971a1111acdeb143bd2f0cfd38..72f9fc4aa0024e01bf58ba5bbd03e9ae64d7db9e 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -341,7 +341,9 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         delete call;
         return PJ_FALSE;
     }
-    call->getAudioRtp().start(ac);
+    std::vector<sfl::AudioCodec *> audioCodecs;
+    audioCodecs.push_back(ac);
+    call->getAudioRtp().start(audioCodecs);
 
     pjsip_dialog *dialog = 0;
 
@@ -807,12 +809,15 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to
         delete call;
         throw VoipLinkException("Could not instantiate codec");
     }
+    std::vector<sfl::AudioCodec *> audioCodecs;
+    audioCodecs.push_back(ac);
+
     // Audio Rtp Session must be initialized before creating initial offer in SDP session
     // since SDES require crypto attribute.
     call->getAudioRtp().initConfig();
     call->getAudioRtp().initSession();
     call->getAudioRtp().initLocalCryptoInfo();
-    call->getAudioRtp().start(ac);
+    call->getAudioRtp().start(audioCodecs);
 
     // Building the local SDP offer
     Sdp *localSDP = call->getLocalSDP();
@@ -865,12 +870,14 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
         delete call;
         throw VoipLinkException("Could not instantiate codec for early media");
     }
+    std::vector<sfl::AudioCodec *> audioCodecs;
+    audioCodecs.push_back(ac);
 
     try {
         call->getAudioRtp().initConfig();
         call->getAudioRtp().initSession();
         call->getAudioRtp().initLocalCryptoInfo();
-        call->getAudioRtp().start(ac);
+        call->getAudioRtp().start(audioCodecs);
     } catch (...) {
         delete call;
         throw VoipLinkException("Could not start rtp session for early media");
@@ -1034,11 +1041,14 @@ SIPVoIPLink::offhold(const std::string& id)
         if (ac == NULL)
             throw VoipLinkException("Could not instantiate codec");
 
+        std::vector<sfl::AudioCodec *> audioCodecs;
+        audioCodecs.push_back(ac);
+
         call->getAudioRtp().initConfig();
         call->getAudioRtp().initSession();
         call->getAudioRtp().restoreLocalContext();
         call->getAudioRtp().initLocalCryptoInfoOnOffHold();
-        call->getAudioRtp().start(ac);
+        call->getAudioRtp().start(audioCodecs);
     } catch (const SdpException &e) {
         ERROR("%s", e.what());
     } catch (...) {
@@ -1756,7 +1766,9 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
             sfl::AudioCodec *ac = Manager::instance().audioCodecFactory.instantiateCodec(pl);
             if (!ac)
                 throw std::runtime_error("Could not instantiate codec");
-            call->getAudioRtp().updateSessionMedia(ac);
+            std::vector<AudioCodec*> audioCodecs;
+            audioCodecs.push_back(ac);
+            call->getAudioRtp().updateSessionMedia(audioCodecs);
         }
     } catch (const SdpException &e) {
         ERROR("%s", e.what());