Skip to content
Snippets Groups Projects
Commit e8a99a82 authored by Rafaël Carré's avatar Rafaël Carré
Browse files

* #6277 : prevent concurrent calls to avcodec_{open,close}

parent 985d1a2f
No related branches found
No related tags found
No related merge requests found
...@@ -1215,6 +1215,16 @@ class ManagerImpl ...@@ -1215,6 +1215,16 @@ class ManagerImpl
*/ */
void audioLayerMutexUnlock(void) { _audiolayerMutex.leaveMutex(); } void audioLayerMutexUnlock(void) { _audiolayerMutex.leaveMutex(); }
/**
* Enter the mutex for libavcodec
*/
void avcodecLock(void) { _avcodecMutex.enterMutex(); }
/**
* Leave the mutex for libavcodec
*/
void avcodecUnlock(void) { _avcodecMutex.leaveMutex(); }
/** /**
* Helper function that creates an MD5 Hash from the credential * Helper function that creates an MD5 Hash from the credential
* information provided as parameters. The hash is computed as * information provided as parameters. The hash is computed as
...@@ -1288,6 +1298,9 @@ class ManagerImpl ...@@ -1288,6 +1298,9 @@ class ManagerImpl
/** Protected current call access */ /** Protected current call access */
ost::Mutex _currentCallMutex; ost::Mutex _currentCallMutex;
/** Protected libavcodec access */
ost::Mutex _avcodecMutex;
/** Audio layer */ /** Audio layer */
AudioLayer* _audiodriver; AudioLayer* _audiodriver;
......
...@@ -53,6 +53,8 @@ extern "C" { ...@@ -53,6 +53,8 @@ extern "C" {
#include <time.h> #include <time.h>
#include <cstdlib> #include <cstdlib>
#include "manager.h"
namespace sfl_video { namespace sfl_video {
namespace { // anonymouse namespace namespace { // anonymouse namespace
...@@ -263,8 +265,10 @@ void VideoReceiveThread::setup() ...@@ -263,8 +265,10 @@ void VideoReceiveThread::setup()
} }
// open codec // open codec
// FIXME: calls to avcodec_open/close should be protected by a mutex Manager::instance().avcodecLock();
if (avcodec_open(decoderCtx_, inputDecoder) < 0) int ret = avcodec_open(decoderCtx_, inputDecoder);
Manager::instance().avcodecUnlock();
if (ret < 0)
{ {
std::cerr << "Could not open codec!" << std::endl; std::cerr << "Could not open codec!" << std::endl;
cleanup(); cleanup();
...@@ -315,9 +319,11 @@ void VideoReceiveThread::cleanup() ...@@ -315,9 +319,11 @@ void VideoReceiveThread::cleanup()
av_free(rawFrame_); av_free(rawFrame_);
// doesn't need to be freed, we didn't use avcodec_alloc_context // doesn't need to be freed, we didn't use avcodec_alloc_context
// FIXME: calls to avcodec_open/close should be protected by a mutex if (decoderCtx_) {
if (decoderCtx_) Manager::instance().avcodecLock();
avcodec_close(decoderCtx_); avcodec_close(decoderCtx_);
Manager::instance().avcodecUnlock();
}
// close the video file // close the video file
if (inputCtx_) if (inputCtx_)
......
...@@ -41,6 +41,8 @@ extern "C" { ...@@ -41,6 +41,8 @@ extern "C" {
#include <libswscale/swscale.h> #include <libswscale/swscale.h>
} }
#include "manager.h"
namespace sfl_video { namespace sfl_video {
void VideoSendThread::print_error(const char *filename, int err) void VideoSendThread::print_error(const char *filename, int err)
...@@ -132,6 +134,7 @@ void VideoSendThread::prepareEncoderContext() ...@@ -132,6 +134,7 @@ void VideoSendThread::prepareEncoderContext()
void VideoSendThread::setup() void VideoSendThread::setup()
{ {
int ret;
av_register_all(); av_register_all();
avdevice_register_all(); avdevice_register_all();
...@@ -198,8 +201,10 @@ void VideoSendThread::setup() ...@@ -198,8 +201,10 @@ void VideoSendThread::setup()
} }
// open codec // open codec
// FIXME: calls to avcodec_open/close should be protected by a mutex Manager::instance().avcodecLock();
if (avcodec_open(inputDecoderCtx_, inputDecoder) < 0) ret = avcodec_open(inputDecoderCtx_, inputDecoder);
Manager::instance().avcodecUnlock();
if (ret < 0)
{ {
std::cerr << "Could not open codec!" << std::endl; std::cerr << "Could not open codec!" << std::endl;
cleanup(); cleanup();
...@@ -236,8 +241,10 @@ void VideoSendThread::setup() ...@@ -236,8 +241,10 @@ void VideoSendThread::setup()
scaledPicture_ = avcodec_alloc_frame(); scaledPicture_ = avcodec_alloc_frame();
// open encoder // open encoder
// FIXME: calls to avcodec_open/close should be protected by a mutex Manager::instance().avcodecLock();
if (avcodec_open(encoderCtx_, encoder) < 0) ret = avcodec_open(encoderCtx_, encoder);
Manager::instance().avcodecUnlock();
if (ret < 0)
{ {
std::cerr << "Could not open encoder" << std::endl; std::cerr << "Could not open encoder" << std::endl;
cleanup(); cleanup();
...@@ -318,7 +325,7 @@ void VideoSendThread::cleanup() ...@@ -318,7 +325,7 @@ void VideoSendThread::cleanup()
av_free(rawFrame_); av_free(rawFrame_);
// close the codecs // close the codecs
// FIXME: calls to avcodec_open/close should be protected by a mutex Manager::instance().avcodecLock();
if (encoderCtx_) if (encoderCtx_)
{ {
avcodec_close(encoderCtx_); avcodec_close(encoderCtx_);
...@@ -326,9 +333,9 @@ void VideoSendThread::cleanup() ...@@ -326,9 +333,9 @@ void VideoSendThread::cleanup()
} }
// doesn't need to be freed, we didn't use avcodec_alloc_context // doesn't need to be freed, we didn't use avcodec_alloc_context
// FIXME: calls to avcodec_open/close should be protected by a mutex
if (inputDecoderCtx_) if (inputDecoderCtx_)
avcodec_close(inputDecoderCtx_); avcodec_close(inputDecoderCtx_);
Manager::instance().avcodecUnlock();
// close the video file // close the video file
if (inputCtx_) if (inputCtx_)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment