#include "libavutil/thread.h"
#include "avcodec.h"
#include "decode.h"
+#include "hwaccel.h"
#include "libavutil/opt.h"
#include "me_cmp.h"
#include "mpegvideo.h"
#include "version.h"
#include <stdlib.h>
#include <stdarg.h>
+#include <stdatomic.h>
#include <limits.h>
#include <float.h>
#if CONFIG_ICONV
#endif
-volatile int ff_avcodec_locked;
-static int volatile entangled_thread_counter = 0;
+static atomic_bool ff_avcodec_locked;
+static atomic_int entangled_thread_counter = ATOMIC_VAR_INIT(0);
static void *codec_mutex;
static void *avformat_mutex;
return i;
}
-static AVHWAccel *first_hwaccel = NULL;
-static AVHWAccel **last_hwaccel = &first_hwaccel;
-
-void av_register_hwaccel(AVHWAccel *hwaccel)
+const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index)
{
- AVHWAccel **p = last_hwaccel;
- hwaccel->next = NULL;
- while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel))
- p = &(*p)->next;
- last_hwaccel = &hwaccel->next;
+ int i;
+ if (!codec->hw_configs || index < 0)
+ return NULL;
+ for (i = 0; i <= index; i++)
+ if (!codec->hw_configs[i])
+ return NULL;
+ return &codec->hw_configs[index]->public;
}
+#if FF_API_USER_VISIBLE_AVHWACCEL
AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel)
{
- return hwaccel ? hwaccel->next : first_hwaccel;
+ return NULL;
}
+void av_register_hwaccel(AVHWAccel *hwaccel)
+{
+}
+#endif
+
int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
{
if (lockmgr_cb) {
int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec)
{
+ _Bool exp = 0;
if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
return 0;
return -1;
}
- if (avpriv_atomic_int_add_and_fetch(&entangled_thread_counter, 1) != 1) {
+ if (atomic_fetch_add(&entangled_thread_counter, 1)) {
av_log(log_ctx, AV_LOG_ERROR,
"Insufficient thread locking. At least %d threads are "
"calling avcodec_open2() at the same time right now.\n",
- entangled_thread_counter);
+ atomic_load(&entangled_thread_counter));
if (!lockmgr_cb)
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);
return AVERROR(EINVAL);
}
- av_assert0(!ff_avcodec_locked);
- ff_avcodec_locked = 1;
+ av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked, &exp, 1));
return 0;
}
int ff_unlock_avcodec(const AVCodec *codec)
{
+ _Bool exp = 1;
if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
return 0;
- av_assert0(ff_avcodec_locked);
- ff_avcodec_locked = 0;
- avpriv_atomic_int_add_and_fetch(&entangled_thread_counter, -1);
+ av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked, &exp, 0));
+ atomic_fetch_add(&entangled_thread_counter, -1);
if (lockmgr_cb) {
if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
return -1;