diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp index df73a76f6a50d49d1a2e59c49eaae6b0a7c975bb..e0d2a51078e0ad372ed4c6a9abcc9dca4029ada9 100644 --- a/src/sip/sipcall.cpp +++ b/src/sip/sipcall.cpp @@ -2492,6 +2492,7 @@ SIPCall::isNewIceMediaRequired(const std::vector<MediaAttribute>& mediaAttrList) bool SIPCall::requestMediaChange(const std::vector<libjami::MediaMap>& mediaList) { + std::lock_guard<std::recursive_mutex> lk {callMutex_}; auto mediaAttrList = MediaAttribute::buildMediaAttributesList(mediaList, isSrtpEnabled()); // Disable video if disabled in the account. @@ -2589,6 +2590,7 @@ SIPCall::currentMediaList() const std::vector<MediaAttribute> SIPCall::getMediaAttributeList() const { + std::lock_guard<std::recursive_mutex> lk {callMutex_}; std::vector<MediaAttribute> mediaList; mediaList.reserve(rtpStreams_.size()); for (auto const& stream : rtpStreams_) @@ -3093,6 +3095,7 @@ SIPCall::enterConference(std::shared_ptr<Conference> conference) void SIPCall::exitConference() { + std::lock_guard<std::recursive_mutex> lk {callMutex_}; JAMI_DBG("[call:%s] Leaving conference", getCallId().c_str()); auto const hasAudio = !getRtpSessionList(MediaType::MEDIA_AUDIO).empty(); @@ -3154,23 +3157,31 @@ SIPCall::setActiveMediaStream(const std::string& accountUri, void SIPCall::setRotation(int streamIdx, int rotation) { - rotation_ = rotation; - if (streamIdx == -1) { - for (const auto& videoRtp : getRtpSessionList(MediaType::MEDIA_VIDEO)) - std::static_pointer_cast<video::VideoRtpSession>(videoRtp)->setRotation(rotation); - } else if (streamIdx > -1 && streamIdx < static_cast<int>(rtpStreams_.size())) { - // Apply request for wanted stream - auto& stream = rtpStreams_[streamIdx]; - if (stream.rtpSession_ && stream.rtpSession_->getMediaType() == MediaType::MEDIA_VIDEO) - std::static_pointer_cast<video::VideoRtpSession>(stream.rtpSession_) - ->setRotation(rotation); - } + // Retrigger on another thread to avoid to lock pjsip + dht::ThreadPool::io().run([w = weak(), streamIdx, rotation] { + if (auto shared = w.lock()) { + std::lock_guard<std::recursive_mutex> lk {shared->callMutex_}; + shared->rotation_ = rotation; + if (streamIdx == -1) { + for (const auto& videoRtp : shared->getRtpSessionList(MediaType::MEDIA_VIDEO)) + std::static_pointer_cast<video::VideoRtpSession>(videoRtp)->setRotation(rotation); + } else if (streamIdx > -1 && streamIdx < static_cast<int>(shared->rtpStreams_.size())) { + // Apply request for wanted stream + auto& stream = shared->rtpStreams_[streamIdx]; + if (stream.rtpSession_ && stream.rtpSession_->getMediaType() == MediaType::MEDIA_VIDEO) + std::static_pointer_cast<video::VideoRtpSession>(stream.rtpSession_) + ->setRotation(rotation); + } + } + }); + } void SIPCall::createSinks(ConfInfo& infos) { - std::lock_guard<std::mutex> lk(sinksMtx_); + std::lock_guard<std::recursive_mutex> lk(callMutex_); + std::lock_guard<std::mutex> lkS(sinksMtx_); if (!hasVideo()) return; diff --git a/test/unitTest/call/conference.cpp b/test/unitTest/call/conference.cpp index e01715c021bafb43a06901e5e1b7c3a463a6ac28..8492d9a5dbf622b48274c93e999edb89e5685e99 100644 --- a/test/unitTest/call/conference.cpp +++ b/test/unitTest/call/conference.cpp @@ -138,6 +138,7 @@ private: std::string carlaId; std::string daviId; std::string confId {}; + std::mutex pInfosMtx_ {}; std::vector<std::map<std::string, std::string>> pInfos_ {}; bool confChanged {false}; @@ -248,6 +249,7 @@ ConferenceTest::registerSignalHandlers() confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::OnConferenceInfosUpdated>( [=](const std::string&, const std::vector<std::map<std::string, std::string>> participantsInfos) { + std::lock_guard<std::mutex> lock(pInfosMtx_); pInfos_ = participantsInfos; for (const auto& infos : participantsInfos) { if (infos.at("uri").find(bobUri) != std::string::npos) { @@ -469,7 +471,7 @@ ConferenceTest::testCreateParticipantsSinks() startConference(); - auto expectedNumberOfParticipants = 3; + auto expectedNumberOfParticipants = 3u; // Check participants number CPPUNIT_ASSERT( @@ -477,6 +479,7 @@ ConferenceTest::testCreateParticipantsSinks() if (not jami::getVideoDeviceMonitor().getDeviceList().empty()) { JAMI_INFO() << "Check sinks if video device available."; + std::lock_guard<std::mutex> lock(pInfosMtx_); for (auto& info : pInfos_) { auto uri = string_remove_suffix(info["uri"], '@'); if (uri == bobUri) { @@ -491,6 +494,7 @@ ConferenceTest::testCreateParticipantsSinks() } } else { JAMI_INFO() << "Check sinks if no video device available."; + std::lock_guard<std::mutex> lock(pInfosMtx_); for (auto& info : pInfos_) { auto uri = string_remove_suffix(info["uri"], '@'); if (uri == bobUri) { @@ -827,6 +831,7 @@ ConferenceTest::testHostAddRmSecondVideo() // Check that alice has two videos attached to the conference auto aliceVideos = [&]() { int result = 0; + std::lock_guard<std::mutex> lock(pInfosMtx_); for (auto i = 0u; i < pInfos_.size(); ++i) if (pInfos_[i]["uri"].find(aliceUri) != std::string::npos) result += 1; @@ -835,7 +840,10 @@ ConferenceTest::testHostAddRmSecondVideo() CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] { return aliceVideos() == 2; })); // Alice removes her second video - pInfos_.clear(); + { + std::lock_guard<std::mutex> lock(pInfosMtx_); + pInfos_.clear(); + } mediaList.pop_back(); libjami::requestMediaChange(aliceId, confId, mediaList); @@ -891,6 +899,7 @@ ConferenceTest::testParticipantAddRmSecondVideo() // Check that bob has two videos attached to the conference auto bobVideos = [&]() { + std::lock_guard<std::mutex> lock(pInfosMtx_); int result = 0; for (auto i = 0u; i < pInfos_.size(); ++i) if (pInfos_[i]["uri"].find(bobUri) != std::string::npos) @@ -900,7 +909,10 @@ ConferenceTest::testParticipantAddRmSecondVideo() CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] { return bobVideos() == 2; })); // Bob removes his second video - pInfos_.clear(); + { + std::lock_guard<std::mutex> lock(pInfosMtx_); + pInfos_.clear(); + } mediaList.pop_back(); libjami::requestMediaChange(bobId, bobCall.callId, mediaList);