Module: sems Branch: master Commit: 04c2f212229c4bb08817bf1c0369a47815fbac3d URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=04c2f212229c4bb08817bf1c0369a47815fbac3d
Author: Raphael Coeffic <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Wed Dec 14 16:31:00 2011 +0100 better support for multiple SDP media + small fixes in related use cases. --- core/AmOfferAnswer.cpp | 3 ++- core/AmPlugIn.cpp | 1 - core/AmRtpAudio.cpp | 15 ++++++++------- core/AmRtpAudio.h | 7 +++---- core/AmRtpStream.cpp | 28 ++++++++++++++++------------ core/AmRtpStream.h | 24 ++++++++++++++++-------- core/AmSession.cpp | 26 ++++++++++++++++---------- 7 files changed, 61 insertions(+), 43 deletions(-) diff --git a/core/AmOfferAnswer.cpp b/core/AmOfferAnswer.cpp index 8a29beb..098e84c 100644 --- a/core/AmOfferAnswer.cpp +++ b/core/AmOfferAnswer.cpp @@ -342,7 +342,8 @@ int AmOfferAnswer::onReplyOut(AmSipReply& reply) // either offer received or no offer at all: // -> force SDP generate_sdp = (state == OA_OfferRecved) - || (state == OA_None); + || (state == OA_None) + || (state == OA_Completed); } } else if (reply.cseq_method == SIP_METH_UPDATE) { diff --git a/core/AmPlugIn.cpp b/core/AmPlugIn.cpp index 8244eaf..99bbdef 100644 --- a/core/AmPlugIn.cpp +++ b/core/AmPlugIn.cpp @@ -467,7 +467,6 @@ int AmPlugIn::getDynPayload(const string& name, int rate, int encoding_param) co /** return 0, or -1 in case of error. */ void AmPlugIn::getPayloads(vector<SdpPayload>& pl_vec) const { - pl_vec.clear(); for (std::map<int,int>::const_iterator it = payload_order.begin(); it != payload_order.end(); ++it) { std::map<int,amci_payload_t*>::const_iterator pl_it = payloads.find(it->second); if(pl_it != payloads.end()){ diff --git a/core/AmRtpAudio.cpp b/core/AmRtpAudio.cpp index f352a34..98d9ab9 100644 --- a/core/AmRtpAudio.cpp +++ b/core/AmRtpAudio.cpp @@ -139,24 +139,25 @@ int AmRtpAudio::write(unsigned int user_ts, unsigned int size) return send(user_ts,(unsigned char*)samples,size); } -void AmRtpAudio::getSdpOffer(SdpMedia& offer) +void AmRtpAudio::getSdpOffer(unsigned int index, SdpMedia& offer) { offer.type = MT_AUDIO; - AmRtpStream::getSdpOffer(offer); + AmRtpStream::getSdpOffer(index,offer); } -void AmRtpAudio::getSdpAnswer(const SdpMedia& offer, SdpMedia& answer) +void AmRtpAudio::getSdpAnswer(unsigned int index, + const SdpMedia& offer, + SdpMedia& answer) { answer.type = MT_AUDIO; - AmRtpStream::getSdpAnswer(offer,answer); + AmRtpStream::getSdpAnswer(index,offer,answer); } -int AmRtpAudio::init(unsigned char media_i, - const AmSdp& local, +int AmRtpAudio::init(const AmSdp& local, const AmSdp& remote) { DBG("AmRtpAudio::init(...)\n"); - if(AmRtpStream::init(media_i,local,remote)){ + if(AmRtpStream::init(local,remote)){ return -1; } diff --git a/core/AmRtpAudio.h b/core/AmRtpAudio.h index 08499d5..118223a 100644 --- a/core/AmRtpAudio.h +++ b/core/AmRtpAudio.h @@ -116,11 +116,10 @@ public: unsigned int nb_samples); // AmRtpStream interface - void getSdpOffer(SdpMedia& offer); - void getSdpAnswer(const SdpMedia& offer, SdpMedia& answer); + void getSdpOffer(unsigned int index, SdpMedia& offer); + void getSdpAnswer(unsigned int index, const SdpMedia& offer, SdpMedia& answer); - int init(unsigned char media_i, - const AmSdp& local, + int init(const AmSdp& local, const AmSdp& remote); void setPlayoutType(PlayoutType type); diff --git a/core/AmRtpStream.cpp b/core/AmRtpStream.cpp index 7f882d9..777bbac 100644 --- a/core/AmRtpStream.cpp +++ b/core/AmRtpStream.cpp @@ -345,7 +345,8 @@ AmRtpStream::AmRtpStream(AmSession* _s, int _if) receiving(true), monitor_rtp_timeout(true), relay_stream(NULL), - relay_enabled(false) + relay_enabled(false), + sdp_media_index(-1) { #ifdef SUPPORT_IPV6 @@ -487,31 +488,34 @@ void AmRtpStream::getSdp(SdpMedia& m) m.dir = SdpMedia::DirBoth; } -void AmRtpStream::getSdpOffer(SdpMedia& offer) +void AmRtpStream::getSdpOffer(unsigned int index, SdpMedia& offer) { + sdp_media_index = index; getSdp(offer); + offer.payloads.clear(); payload_provider->getPayloads(offer.payloads); } -void AmRtpStream::getSdpAnswer(const SdpMedia& offer, SdpMedia& answer) +void AmRtpStream::getSdpAnswer(unsigned int index, const SdpMedia& offer, SdpMedia& answer) { + sdp_media_index = index; getSdp(answer); offer.calcAnswer(payload_provider,answer); } -int AmRtpStream::init(unsigned char media_i, - const AmSdp& local, +int AmRtpStream::init(const AmSdp& local, const AmSdp& remote) { - if((media_i >= local.media.size()) || - (media_i >= remote.media.size()) ) { + if((sdp_media_index < 0) || + ((unsigned)sdp_media_index >= local.media.size()) || + ((unsigned)sdp_media_index >= remote.media.size()) ) { - ERROR("Media index %i is invalid, either within local or remote SDP (or both)",media_i); + ERROR("Media index %i is invalid, either within local or remote SDP (or both)",sdp_media_index); return -1; } - const SdpMedia& local_media = local.media[media_i]; - const SdpMedia& remote_media = remote.media[media_i]; + const SdpMedia& local_media = local.media[sdp_media_index]; + const SdpMedia& remote_media = remote.media[sdp_media_index]; payloads.clear(); pl_map.clear(); @@ -597,14 +601,14 @@ int AmRtpStream::init(unsigned char media_i, local_telephone_event_pt.reset(local.telephoneEventPayload()); - if(remote_media.send) { + if(local_media.recv) { resume(); } else { pause(); } - if(remote_media.recv && !hold + if(local_media.send && !hold && (remote_media.port != 0) #ifndef SUPPORT_IPV6 && (r_saddr.sin_addr.s_addr != 0) diff --git a/core/AmRtpStream.h b/core/AmRtpStream.h index 10a7b29..22da0a3 100644 --- a/core/AmRtpStream.h +++ b/core/AmRtpStream.h @@ -131,6 +131,10 @@ protected: // mapping from local payload type to PayloadMapping PayloadMappingTable pl_map; + /** SDP media slot number (n-th media line) */ + int sdp_media_index; + + /** RTP sequence number */ unsigned int sequence; /** @@ -307,6 +311,9 @@ public: void setPayloadProvider(AmPayloadProvider* pl_prov); + int getSdpMediaIndex() { return sdp_media_index; } + int getPayloadType() { return payload; } + /** * send a DTMF as RTP payload (RFC4733) * @param event event ID (e.g. key press), see rfc @@ -316,26 +323,27 @@ public: /** * Generate an SDP offer based on the stream capabilities. + * @param index index of the SDP media within the SDP. * @param offer the local offer to be filled/completed. */ - virtual void getSdpOffer(SdpMedia& offer); + virtual void getSdpOffer(unsigned int index, SdpMedia& offer); /** * Generate an answer for the given SDP media based on the stream capabilities. + * @param index index of the SDP media within the SDP. * @param offer the remote offer. * @param answer the local answer to be filled/completed. */ - virtual void getSdpAnswer(const SdpMedia& offer, SdpMedia& answer); + virtual void getSdpAnswer(unsigned int index, const SdpMedia& offer, SdpMedia& answer); /** * Enables RTP stream. - * @param sdp_payload payload from the SDP message. - * @warning start() must have been called so that play and record work. - * @warning It should be called only if the stream has been completly initialized, - * @warning and only once per session. Use resume() then. + * @param local the SDP message generated by the local UA. + * @param remote the SDP message generated by the remote UA. + * @warning It is necessary to call getSdpOffer/getSdpAnswer prior to init(...) + * @warning so that the internal SDP media line index is set properly. */ - virtual int init(unsigned char media_i, - const AmSdp& local, + virtual int init(const AmSdp& local, const AmSdp& remote); /** diff --git a/core/AmSession.cpp b/core/AmSession.cpp index a9350ef..5aba97c 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -957,10 +957,18 @@ bool AmSession::getSdpOffer(AmSdp& offer) // TODO: support mutiple media types (needs multiples RTP streams) // TODO: support update instead of clearing everything - offer.media.clear(); - offer.media.push_back(SdpMedia()); - RTPStream()->getSdpOffer(offer.media.back()); + if(RTPStream()->getSdpMediaIndex() < 0) + offer.media.clear(); + + if(!offer.media.size()) { + offer.media.push_back(SdpMedia()); + RTPStream()->getSdpOffer(0,offer.media.back()); + } + else { + RTPStream()->getSdpOffer(RTPStream()->getSdpMediaIndex(), + offer.media.back()); + } return true; } @@ -981,6 +989,7 @@ bool AmSession::getSdpAnswer(const AmSdp& offer, AmSdp& answer) answer.media.clear(); bool audio_1st_stream = true; + unsigned int media_index = 0; for(vector<SdpMedia>::const_iterator m_it = offer.media.begin(); m_it != offer.media.end(); ++m_it) { @@ -991,7 +1000,7 @@ bool AmSession::getSdpAnswer(const AmSdp& offer, AmSdp& answer) && audio_1st_stream && (m_it->port != 0) ) { - RTPStream()->getSdpAnswer(*m_it,answer_media); + RTPStream()->getSdpAnswer(media_index,*m_it,answer_media); if(answer_media.payloads.empty() || ((answer_media.payloads.size() == 1) && (answer_media.payloads[0].encoding_name == "telephone-event")) @@ -1018,6 +1027,8 @@ bool AmSession::getSdpAnswer(const AmSdp& offer, AmSdp& answer) } answer_media.attributes.clear(); } + + media_index++; } return true; @@ -1045,13 +1056,8 @@ int AmSession::onSdpCompleted(const AmSdp& local_sdp, const AmSdp& remote_sdp) return -1; } - // TODO: - // - get the right media ID - // - check if the stream coresponding to the media ID - // should be created or updated - // lockAudio(); - int ret = RTPStream()->init(0,local_sdp,remote_sdp); + int ret = RTPStream()->init(local_sdp,remote_sdp); unlockAudio(); if(ret){ _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
