You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-11-06 08:29:25 +02:00
libavcodec/utils.c: simplify avcodec locking with atomics
Also makes it more robust than using volatiles. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
This commit is contained in:
@@ -246,7 +246,6 @@ int ff_init_buffer_info(AVCodecContext *s, AVFrame *frame);
|
|||||||
|
|
||||||
void ff_color_frame(AVFrame *frame, const int color[4]);
|
void ff_color_frame(AVFrame *frame, const int color[4]);
|
||||||
|
|
||||||
extern volatile int ff_avcodec_locked;
|
|
||||||
int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec);
|
int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec);
|
||||||
int ff_unlock_avcodec(const AVCodec *codec);
|
int ff_unlock_avcodec(const AVCodec *codec);
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = NULL;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
volatile int ff_avcodec_locked;
|
static atomic_bool ff_avcodec_locked;
|
||||||
static atomic_int entangled_thread_counter = ATOMIC_VAR_INIT(0);
|
static atomic_int entangled_thread_counter = ATOMIC_VAR_INIT(0);
|
||||||
static void *codec_mutex;
|
static void *codec_mutex;
|
||||||
static void *avformat_mutex;
|
static void *avformat_mutex;
|
||||||
@@ -1937,6 +1937,7 @@ int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
|
|||||||
|
|
||||||
int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec)
|
int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec)
|
||||||
{
|
{
|
||||||
|
_Bool exp = 0;
|
||||||
if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
|
if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1952,22 +1953,21 @@ int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec)
|
|||||||
atomic_load(&entangled_thread_counter));
|
atomic_load(&entangled_thread_counter));
|
||||||
if (!lockmgr_cb)
|
if (!lockmgr_cb)
|
||||||
av_log(log_ctx, AV_LOG_ERROR, "No lock manager is set, please see av_lockmgr_register()\n");
|
av_log(log_ctx, AV_LOG_ERROR, "No lock manager is set, please see av_lockmgr_register()\n");
|
||||||
ff_avcodec_locked = 1;
|
atomic_store(&ff_avcodec_locked, 1);
|
||||||
ff_unlock_avcodec(codec);
|
ff_unlock_avcodec(codec);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
av_assert0(!ff_avcodec_locked);
|
av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked, &exp, 1));
|
||||||
ff_avcodec_locked = 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_unlock_avcodec(const AVCodec *codec)
|
int ff_unlock_avcodec(const AVCodec *codec)
|
||||||
{
|
{
|
||||||
|
_Bool exp = 1;
|
||||||
if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
|
if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
av_assert0(ff_avcodec_locked);
|
av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked, &exp, 0));
|
||||||
ff_avcodec_locked = 0;
|
|
||||||
atomic_fetch_add(&entangled_thread_counter, -1);
|
atomic_fetch_add(&entangled_thread_counter, -1);
|
||||||
if (lockmgr_cb) {
|
if (lockmgr_cb) {
|
||||||
if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
|
if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
|
||||||
|
|||||||
Reference in New Issue
Block a user