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