diff --git a/src/media/libav_utils.h b/src/media/libav_utils.h
index 942933c95c93a8f8ea5aa5d510f01066714743ad..6e91a785f86f948cde38d61a39ce12b2bd96d373 100644
--- a/src/media/libav_utils.h
+++ b/src/media/libav_utils.h
@@ -24,11 +24,14 @@
 #include <vector>
 #include <map>
 #include <string>
+#include <memory>
 
 extern "C" {
 struct AVDictionary;
 struct AVFrame;
 struct AVPixFmtDescriptor;
+struct AVBufferRef;
+void av_buffer_unref(AVBufferRef **buf);
 }
 
 namespace jami {
@@ -51,5 +54,11 @@ void fillWithBlack(AVFrame* frame);
 
 void fillWithSilence(AVFrame* frame);
 
+struct AVBufferRef_deleter {
+    void operator()(AVBufferRef* buf) const { av_buffer_unref(&buf); }
+};
+
+typedef std::unique_ptr<AVBufferRef, AVBufferRef_deleter> AVBufferPtr;
+
 } // namespace libav_utils
 } // namespace jami
diff --git a/src/media/video/video_receive_thread.cpp b/src/media/video/video_receive_thread.cpp
index e86c35f86c3b5e60771b0d190b93b66040f8968b..42274a8f9e871409654c47ef2f8e0a97f3a1f4ee 100644
--- a/src/media/video/video_receive_thread.cpp
+++ b/src/media/video/video_receive_thread.cpp
@@ -92,10 +92,16 @@ VideoReceiveThread::setup()
     JAMI_DBG("[%p] Setupping video receiver", this);
 
     videoDecoder_.reset(new MediaDecoder([this](const std::shared_ptr<MediaFrame>& frame) mutable {
-        if (auto displayMatrix = displayMatrix_)
+        libav_utils::AVBufferPtr displayMatrix;
+        {
+            std::lock_guard<std::mutex> l(rotationMtx_);
+            if (displayMatrix_)
+                displayMatrix.reset(av_buffer_ref(displayMatrix_.get()));
+        }
+        if (displayMatrix)
             av_frame_new_side_data_from_buf(frame->pointer(),
                                             AV_FRAME_DATA_DISPLAYMATRIX,
-                                            av_buffer_ref(displayMatrix.get()));
+                                            displayMatrix.release());
         publishFrame(std::static_pointer_cast<VideoFrame>(frame));
     }));
     videoDecoder_->setResolutionChangedCallback([this](int width, int height) {
@@ -303,14 +309,10 @@ VideoReceiveThread::getInfo() const
 void
 VideoReceiveThread::setRotation(int angle)
 {
-    std::shared_ptr<AVBufferRef> displayMatrix {av_buffer_alloc(sizeof(int32_t) * 9),
-                                                [](AVBufferRef* buf) {
-                                                    av_buffer_unref(&buf);
-                                                }};
-    if (displayMatrix) {
-        av_display_rotation_set(reinterpret_cast<int32_t*>(displayMatrix->data), angle);
-        displayMatrix_ = std::move(displayMatrix);
-    }
+    libav_utils::AVBufferPtr displayMatrix(av_buffer_alloc(sizeof(int32_t) * 9));
+    av_display_rotation_set(reinterpret_cast<int32_t*>(displayMatrix->data), angle);
+    std::lock_guard<std::mutex> l(rotationMtx_);
+    displayMatrix_ = std::move(displayMatrix);
 }
 
 } // namespace video
diff --git a/src/media/video/video_receive_thread.h b/src/media/video/video_receive_thread.h
index c4b156c6839069ee846bf0469d3d3376705322f7..b1b1998a1f0c78354e30e3a97e586ac5dcc3c50c 100644
--- a/src/media/video/video_receive_thread.h
+++ b/src/media/video/video_receive_thread.h
@@ -31,6 +31,7 @@
 #include "media_stream.h"
 #include "threadloop.h"
 #include "noncopyable.h"
+#include "libav_utils.h"
 
 #include <functional>
 #include <map>
@@ -106,7 +107,8 @@ private:
     uint16_t mtu_;
     int rotation_ {0};
 
-    std::shared_ptr<AVBufferRef> displayMatrix_;
+    std::mutex rotationMtx_;
+    libav_utils::AVBufferPtr displayMatrix_;
 
     static int interruptCb(void* ctx);
     static int readFunction(void* opaque, uint8_t* buf, int buf_size);