Skip to content
Snippets Groups Projects
Commit c3d0e5eb authored by Mohamed Chibani's avatar Mohamed Chibani
Browse files

Mute audio: do not change media direction

Mute/un-mute audio is done only locally, i.e. without requesting
a media change (re-invite) as done for the video, thus the media
direction in the SDP must not change for the audio stream.

Gitlab: #688

Change-Id: I3775a29f6c566a159d5b9269b4d9462ab4e3c36f
parent 0f0bb5d8
No related branches found
No related tags found
No related merge requests found
......@@ -55,6 +55,12 @@ using std::stringstream;
static constexpr int POOL_INITIAL_SIZE = 16384;
static constexpr int POOL_INCREMENT_SIZE = POOL_INITIAL_SIZE;
static std::map<MediaDirection, const char*> DIRECTION_STR {{MediaDirection::SENDRECV, "sendrecv"},
{MediaDirection::SENDONLY, "sendonly"},
{MediaDirection::RECVONLY, "recvonly"},
{MediaDirection::INACTIVE, "inactive"},
{MediaDirection::UNKNOWN, "unknown"}};
Sdp::Sdp(const std::string& id)
: memPool_(nullptr, [](pj_pool_t* pool) { pj_pool_release(pool); })
, publishedIpAddr_()
......@@ -159,48 +165,66 @@ Sdp::generateSdesAttribute()
return pjmedia_sdp_attr_create(memPool_.get(), "crypto", &val);
}
// Legacy direction inference
char const*
Sdp::mediaDirection(MediaType type, bool onHold)
{
return onHold ? (type == MediaType::MEDIA_AUDIO ? "sendonly" : "inactive") : "sendrecv";
}
// Direction inference based on RFC-3264 and RFC-6337
char const*
Sdp::mediaDirection(const MediaAttribute& mediaAttr)
{
if (not mediaAttr.enabled_)
return "inactive";
if (not mediaAttr.enabled_) {
return DIRECTION_STR[MediaDirection::INACTIVE];
}
// Since mute/un-mute audio is only done locally (RTP packets
// are still sent to the peer), the media direction must be
// set to "sendrecv" regardless of the mute state.
if (mediaAttr.type_ == MediaType::MEDIA_AUDIO) {
return DIRECTION_STR[MediaDirection::SENDRECV];
}
if (mediaAttr.muted_) {
if (mediaAttr.onHold_)
return "inactive";
return "recvonly";
if (mediaAttr.onHold_) {
return DIRECTION_STR[MediaDirection::INACTIVE];
}
return DIRECTION_STR[MediaDirection::RECVONLY];
}
if (mediaAttr.onHold_)
return "sendonly";
if (mediaAttr.onHold_) {
return DIRECTION_STR[MediaDirection::SENDONLY];
}
return "sendrecv";
return DIRECTION_STR[MediaDirection::SENDRECV];
}
MediaDirection
Sdp::getMediaDirection(pjmedia_sdp_media* media)
{
if (pjmedia_sdp_attr_find2(media->attr_count, media->attr, "sendrecv", nullptr) != nullptr) {
if (pjmedia_sdp_attr_find2(media->attr_count,
media->attr,
DIRECTION_STR[MediaDirection::SENDRECV],
nullptr)
!= nullptr) {
return MediaDirection::SENDRECV;
}
if (pjmedia_sdp_attr_find2(media->attr_count, media->attr, "sendonly", nullptr) != nullptr) {
if (pjmedia_sdp_attr_find2(media->attr_count,
media->attr,
DIRECTION_STR[MediaDirection::SENDONLY],
nullptr)
!= nullptr) {
return MediaDirection::SENDONLY;
}
if (pjmedia_sdp_attr_find2(media->attr_count, media->attr, "recvonly", nullptr) != nullptr) {
if (pjmedia_sdp_attr_find2(media->attr_count,
media->attr,
DIRECTION_STR[MediaDirection::RECVONLY],
nullptr)
!= nullptr) {
return MediaDirection::RECVONLY;
}
if (pjmedia_sdp_attr_find2(media->attr_count, media->attr, "inactive", nullptr) != nullptr) {
if (pjmedia_sdp_attr_find2(media->attr_count,
media->attr,
DIRECTION_STR[MediaDirection::INACTIVE],
nullptr)
!= nullptr) {
return MediaDirection::INACTIVE;
}
......@@ -790,10 +814,13 @@ Sdp::getMediaDescriptions(const pjmedia_sdp_session* session, bool remote) const
}
}
descr.onHold = pjmedia_sdp_attr_find2(media->attr_count, media->attr, "sendonly", nullptr)
descr.onHold = pjmedia_sdp_attr_find2(media->attr_count,
media->attr,
DIRECTION_STR[MediaDirection::SENDONLY],
nullptr)
|| pjmedia_sdp_attr_find2(media->attr_count,
media->attr,
"inactive",
DIRECTION_STR[MediaDirection::INACTIVE],
nullptr);
descr.direction_ = getMediaDirection(media);
......
......@@ -195,6 +195,7 @@ public:
std::vector<std::string> getIceCandidates(unsigned media_index) const;
void clearIce();
SdpDirection getSdpDirection() const { return sdpDirection_; };
static const char* getSdpDirectionStr(SdpDirection direction);
......@@ -221,60 +222,6 @@ private:
static void clearIce(pjmedia_sdp_session* session);
/**
* The pool to allocate memory
*/
std::unique_ptr<pj_pool_t, std::function<void(pj_pool_t*)>> memPool_;
/** negotiator */
pjmedia_sdp_neg* negotiator_ {nullptr};
/**
* Local SDP
*/
pjmedia_sdp_session* localSession_ {nullptr};
/**
* Remote SDP
*/
pjmedia_sdp_session* remoteSession_ {nullptr};
/**
* The negotiated SDP remote session
* Explanation: each endpoint's offer is negotiated, and a new sdp offer results from this
* negotiation, with the compatible media from each part
*/
const pjmedia_sdp_session* activeLocalSession_ {nullptr};
/**
* The negotiated SDP remote session
* Explanation: each endpoint's offer is negotiated, and a new sdp offer results from this
* negotiation, with the compatible media from each part
*/
const pjmedia_sdp_session* activeRemoteSession_ {nullptr};
/**
* Codec Map used for offer
*/
std::vector<std::shared_ptr<AccountCodecInfo>> audio_codec_list_;
std::vector<std::shared_ptr<AccountCodecInfo>> video_codec_list_;
std::string publishedIpAddr_;
pj_uint16_t publishedIpAddrType_;
uint16_t localAudioRtpPort_ {0};
uint16_t localAudioRtcpPort_ {0};
uint16_t localVideoRtpPort_ {0};
uint16_t localVideoRtcpPort_ {0};
unsigned int telephoneEventPayload_;
// The call Id of the SDP owner
std::string sessionName_ {};
// Offer/Answer flag.
SdpDirection sdpDirection_ {SdpDirection::NONE};
/*
* Build the sdp media section
* Add rtpmap field if necessary
......@@ -282,7 +229,6 @@ private:
pjmedia_sdp_media* addMediaDescription(const MediaAttribute& mediaAttr);
// Determine media direction
char const* mediaDirection(MediaType type, bool onHold);
char const* mediaDirection(const MediaAttribute& mediaAttr);
// Get media direction
......@@ -321,6 +267,48 @@ private:
std::shared_ptr<AccountCodecInfo> findCodecByPayload(const unsigned payloadType);
std::shared_ptr<AccountCodecInfo> findCodecBySpec(const std::string& codecName,
const unsigned clockrate = 0) const;
// Data members
std::unique_ptr<pj_pool_t, std::function<void(pj_pool_t*)>> memPool_;
pjmedia_sdp_neg* negotiator_ {nullptr};
pjmedia_sdp_session* localSession_ {nullptr};
pjmedia_sdp_session* remoteSession_ {nullptr};
/**
* The negotiated SDP remote session
* Explanation: each endpoint's offer is negotiated, and a new sdp offer results from this
* negotiation, with the compatible media from each part
*/
const pjmedia_sdp_session* activeLocalSession_ {nullptr};
/**
* The negotiated SDP remote session
* Explanation: each endpoint's offer is negotiated, and a new sdp offer results from this
* negotiation, with the compatible media from each part
*/
const pjmedia_sdp_session* activeRemoteSession_ {nullptr};
/**
* Codec Map used for offer
*/
std::vector<std::shared_ptr<AccountCodecInfo>> audio_codec_list_;
std::vector<std::shared_ptr<AccountCodecInfo>> video_codec_list_;
std::string publishedIpAddr_;
pj_uint16_t publishedIpAddrType_;
uint16_t localAudioRtpPort_ {0};
uint16_t localAudioRtcpPort_ {0};
uint16_t localVideoRtpPort_ {0};
uint16_t localVideoRtcpPort_ {0};
unsigned int telephoneEventPayload_;
// The call Id of the SDP owner
std::string sessionName_ {};
// Offer/Answer flag.
SdpDirection sdpDirection_ {SdpDirection::NONE};
};
} // namespace jami
......@@ -771,8 +771,8 @@ SipBasicCallTest::hold_resume_test()
auto& sdp = call->getSDP();
auto mediaStreams = sdp.getMediaSlots();
for (auto const& media : mediaStreams) {
CPPUNIT_ASSERT_EQUAL(media.first.direction_, MediaDirection::SENDRECV);
CPPUNIT_ASSERT_EQUAL(media.second.direction_, MediaDirection::SENDRECV);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.first.direction_);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.second.direction_);
}
}
......@@ -783,8 +783,8 @@ SipBasicCallTest::hold_resume_test()
auto& sdp = call->getSDP();
auto mediaStreams = sdp.getMediaSlots();
for (auto const& media : mediaStreams) {
CPPUNIT_ASSERT_EQUAL(media.first.direction_, MediaDirection::SENDRECV);
CPPUNIT_ASSERT_EQUAL(media.second.direction_, MediaDirection::SENDRECV);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.first.direction_);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.second.direction_);
}
}
......@@ -820,8 +820,13 @@ SipBasicCallTest::hold_resume_test()
auto& sdp = call->getSDP();
auto mediaStreams = sdp.getMediaSlots();
for (auto const& media : mediaStreams) {
CPPUNIT_ASSERT_EQUAL(media.first.direction_, MediaDirection::SENDONLY);
CPPUNIT_ASSERT_EQUAL(media.second.direction_, MediaDirection::RECVONLY);
if (media.first.type == MediaType::MEDIA_AUDIO) {
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.first.direction_);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.second.direction_);
} else {
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDONLY, media.first.direction_);
CPPUNIT_ASSERT_EQUAL(MediaDirection::RECVONLY, media.second.direction_);
}
}
}
......@@ -832,8 +837,13 @@ SipBasicCallTest::hold_resume_test()
auto& sdp = call->getSDP();
auto mediaStreams = sdp.getMediaSlots();
for (auto const& media : mediaStreams) {
CPPUNIT_ASSERT_EQUAL(media.first.direction_, MediaDirection::RECVONLY);
CPPUNIT_ASSERT_EQUAL(media.second.direction_, MediaDirection::SENDONLY);
if (media.first.type == MediaType::MEDIA_AUDIO) {
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.first.direction_);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.second.direction_);
} else {
CPPUNIT_ASSERT_EQUAL(MediaDirection::RECVONLY, media.first.direction_);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDONLY, media.second.direction_);
}
}
}
......@@ -1053,8 +1063,8 @@ SipBasicCallTest::blind_transfer_test()
auto& sdp = call->getSDP();
auto mediaStreams = sdp.getMediaSlots();
for (auto const& media : mediaStreams) {
CPPUNIT_ASSERT_EQUAL(media.first.direction_, MediaDirection::SENDRECV);
CPPUNIT_ASSERT_EQUAL(media.second.direction_, MediaDirection::SENDRECV);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.first.direction_);
CPPUNIT_ASSERT_EQUAL(MediaDirection::SENDRECV, media.second.direction_);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment