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);