From 8ca7dd3acba16cf4b8bacb33530158f1c87294d7 Mon Sep 17 00:00:00 2001 From: Mohamed Chibani Date: Wed, 19 Jan 2022 15:22:01 -0500 Subject: [PATCH] conference/auto-answer: fix request media change In conference and auto-answer mode, if the remote peer requests a media change, the remote media was used to configure the local media. This is bad, since if the remote muted its audio, it will also mute the local audio. Now, the existing media will not be modified, and the new media will be automatically added if any. Gitlab: #688 Change-Id: Id5388ed916eaa5755202b4b5b5fad118f0dc9c1e --- src/conference.cpp | 17 +++++++++++++++-- src/sip/sipcall.cpp | 33 +++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/conference.cpp b/src/conference.cpp index a4ff0840a..eac0925df 100644 --- a/src/conference.cpp +++ b/src/conference.cpp @@ -549,12 +549,25 @@ Conference::handleMediaChangeRequest(const std::shared_ptr& call, auto updateMixer = call->checkMediaChangeRequest(remoteMediaList); // NOTE: - // Since this is a conference, accept any media change request. + // Since this is a conference, newly added media will be also + // accepted. // This also means that if original call was an audio-only call, // the local camera will be enabled, unless the video is disabled // in the account settings. - call->answerMediaChangeRequest(remoteMediaList); + std::vector newMediaList; + newMediaList.reserve(remoteMediaList.size()); + for (auto const& media : call->getMediaAttributeList()) { + newMediaList.emplace_back(MediaAttribute::toMediaMap(media)); + } + + if (remoteMediaList.size() > newMediaList.size()) { + for (auto idx = newMediaList.size(); idx < remoteMediaList.size(); idx++) { + newMediaList.emplace_back(remoteMediaList[idx]); + } + } + + call->answerMediaChangeRequest(newMediaList); call->enterConference(shared_from_this()); if (updateMixer and getState() == Conference::State::ACTIVE_ATTACHED) { diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp index 5b2c9679d..ab60254b1 100644 --- a/src/sip/sipcall.cpp +++ b/src/sip/sipcall.cpp @@ -2497,15 +2497,15 @@ SIPCall::checkMediaChangeRequest(const std::vector& remoteMedia JAMI_DBG("[call:%s] Received a media change request", getCallId().c_str()); - auto remoteMediaAtrrList = MediaAttribute::buildMediaAttributesList(remoteMediaList, + auto remoteMediaAttrList = MediaAttribute::buildMediaAttributesList(remoteMediaList, isSrtpEnabled()); - if (remoteMediaAtrrList.size() != rtpStreams_.size()) + if (remoteMediaAttrList.size() != rtpStreams_.size()) return true; for (size_t i = 0; i < rtpStreams_.size(); i++) { - if (remoteMediaAtrrList[i].type_ != rtpStreams_[i].mediaAttribute_->type_) + if (remoteMediaAttrList[i].type_ != rtpStreams_[i].mediaAttribute_->type_) return true; - if (remoteMediaAtrrList[i].enabled_ != rtpStreams_[i].mediaAttribute_->enabled_) + if (remoteMediaAttrList[i].enabled_ != rtpStreams_[i].mediaAttribute_->enabled_) return true; } @@ -2533,12 +2533,25 @@ SIPCall::handleMediaChangeRequest(const std::vector& remoteMedi if (account->isAutoAnswerEnabled()) { // NOTE: - // Since the auto-answer is enabled in the account, media change requests - // are automatically accepted too. This also means that if the original - // call was an audio-only call, and the remote added the video, the local - // camera will be enabled, unless the video is disabled in the account - // settings. - answerMediaChangeRequest(remoteMediaList); + // Since the auto-answer is enabled in the account, newly + // added media are accepted too. + // This also means that if original call was an audio-only call, + // the local camera will be enabled, unless the video is disabled + // in the account settings. + + std::vector newMediaList; + newMediaList.reserve(remoteMediaList.size()); + for (auto const& stream : rtpStreams_) { + newMediaList.emplace_back(MediaAttribute::toMediaMap(*stream.mediaAttribute_)); + } + + assert(remoteMediaList.size() > 0); + if (remoteMediaList.size() > newMediaList.size()) { + for (auto idx = newMediaList.size(); idx < remoteMediaList.size(); idx++) { + newMediaList.emplace_back(remoteMediaList[idx]); + } + } + answerMediaChangeRequest(newMediaList); return; }