diff --git a/src/media/audio/portaudio/portaudiolayer.cpp b/src/media/audio/portaudio/portaudiolayer.cpp
index 639f4d79c91c7ae53d607135c3d7daf09c15ed7b..122392e946e4f5fef7c526d564e6230238614354 100644
--- a/src/media/audio/portaudio/portaudiolayer.cpp
+++ b/src/media/audio/portaudio/portaudiolayer.cpp
@@ -24,9 +24,10 @@
 
 #include <portaudio.h>
 
-#include <algorithm>
 #include <windows.h>
 
+#include <algorithm>
+
 namespace jami {
 
 enum Direction { Input = 0, Output = 1, IO = 2, End = 3 };
@@ -61,7 +62,9 @@ struct PortAudioLayer::PortAudioLayerImpl
     bool outputInitialized_ {false};
 
     std::array<PaStream*, static_cast<int>(Direction::End)> streams_;
+    mutable std::mutex streamsMutex_;
     bool paStopStream(Direction streamDirection);
+    bool hasFullDuplexStream() const;
 
     AudioDeviceNotificationClientPtr audioDeviceNotificationClient_;
     // The following flag used to debounce the device state changes,
@@ -214,55 +217,52 @@ PortAudioLayer::startStream(AudioDeviceType stream)
 void
 PortAudioLayer::stopStream(AudioDeviceType stream)
 {
-    auto stopPlayback = [this](bool fullDuplexMode = false) -> bool {
-        std::lock_guard lock(mutex_);
-        if (status_.load() != Status::Started)
-            return false;
-        bool stopped = false;
-        if (fullDuplexMode)
-            stopped = pimpl_->paStopStream(Direction::IO);
-        else
-            stopped = pimpl_->paStopStream(Direction::Output);
-        if (stopped)
-            status_.store(Status::Idle);
-        return stopped;
-    };
+    std::lock_guard lock(mutex_);
+    if (status_.load() != Status::Started)
+        return;
 
     bool stopped = false;
     switch (stream) {
     case AudioDeviceType::ALL:
-        if (pimpl_->streams_[Direction::IO]) {
-            stopped = stopPlayback(true);
+        if (pimpl_->hasFullDuplexStream()) {
+            stopped = pimpl_->paStopStream(Direction::IO);
+            JAMI_DBG("PortAudioLayer full-duplex stream stopped");
         } else {
-            stopped = pimpl_->paStopStream(Direction::Input) && stopPlayback();
+            if (pimpl_->paStopStream(Direction::Output)) {
+                playbackChanged(false);
+                stopped = true;
+                JAMI_DBG("PortAudioLayer output stream stopped");
+            }
+            if (pimpl_->paStopStream(Direction::Input)) {
+                recordChanged(false);
+                stopped = true;
+                JAMI_DBG("PortAudioLayer input stream stopped");
+            }
         }
-        if (stopped) {
-            recordChanged(false);
-            playbackChanged(false);
-            JAMI_DBG("PortAudioLayer I/O streams stopped");
-        } else
-            return;
         break;
     case AudioDeviceType::CAPTURE:
         if (pimpl_->paStopStream(Direction::Input)) {
             recordChanged(false);
             JAMI_DBG("PortAudioLayer input stream stopped");
-        } else
-            return;
+            stopped = true;
+        }
         break;
     case AudioDeviceType::PLAYBACK:
     case AudioDeviceType::RINGTONE:
-        if (stopPlayback()) {
+        if (pimpl_->paStopStream(Direction::Output)) {
             playbackChanged(false);
+            stopped = true;
             JAMI_DBG("PortAudioLayer output stream stopped");
-        } else
-            return;
+        }
         break;
     }
 
-    // Flush the ring buffers
-    flushUrgent();
-    flushMain();
+    // Flush the ring buffers if any streams were stopped
+    if (stopped) {
+        JAMI_DBG("PortAudioLayer streams stopped, flushing buffers");
+        flushUrgent();
+        flushMain();
+    }
 }
 
 void
@@ -417,6 +417,7 @@ PortAudioLayer::PortAudioLayerImpl::init(PortAudioLayer& parent)
     initInput(parent);
     initOutput(parent);
 
+    std::lock_guard lock(streamsMutex_);
     std::fill(std::begin(streams_), std::end(streams_), nullptr);
 }
 
@@ -601,11 +602,12 @@ bool
 PortAudioLayer::PortAudioLayerImpl::initInputStream(PortAudioLayer& parent)
 {
     JAMI_DBG("Open PortAudio Input Stream");
+    std::lock_guard lock(streamsMutex_);
     auto& stream = streams_[Direction::Input];
     auto apiIndex = getApiIndexByType(AudioDeviceType::CAPTURE);
     if (apiIndex != paNoDevice) {
         openStreamDevice(
-            &streams_[Direction::Input],
+            &stream,
             apiIndex,
             Direction::Input,
             [](const void* inputBuffer,
@@ -643,6 +645,7 @@ bool
 PortAudioLayer::PortAudioLayerImpl::initOutputStream(PortAudioLayer& parent)
 {
     JAMI_DBG("Open PortAudio Output Stream");
+    std::lock_guard lock(streamsMutex_);
     auto& stream = streams_[Direction::Output];
     auto apiIndex = getApiIndexByType(AudioDeviceType::PLAYBACK);
     if (apiIndex != paNoDevice) {
@@ -692,6 +695,7 @@ PortAudioLayer::PortAudioLayerImpl::initFullDuplexStream(PortAudioLayer& parent)
     }
 
     JAMI_DBG("Open PortAudio Full-duplex input/output stream");
+    std::lock_guard lock(streamsMutex_);
     auto& stream = streams_[Direction::IO];
     openFullDuplexStream(
         &stream,
@@ -728,6 +732,7 @@ PortAudioLayer::PortAudioLayerImpl::initFullDuplexStream(PortAudioLayer& parent)
 bool
 PortAudioLayer::PortAudioLayerImpl::paStopStream(Direction streamDirection)
 {
+    std::lock_guard lock(streamsMutex_);
     PaStream* paStream = streams_[streamDirection];
     if (!paStream)
         return false;
@@ -754,6 +759,12 @@ PortAudioLayer::PortAudioLayerImpl::paStopStream(Direction streamDirection)
     return true;
 };
 
+bool PortAudioLayer::PortAudioLayerImpl::hasFullDuplexStream() const
+{
+    std::lock_guard lock(streamsMutex_);
+    return streams_[Direction::IO] != nullptr;
+}
+
 int
 PortAudioLayer::PortAudioLayerImpl::paOutputCallback(PortAudioLayer& parent,
                                                      const int16_t* inputBuffer,